目的
@H_502_3@熟悉openssl生成密钥和证书对,熟悉go中crypto/tls的用法
@H_502_3@
@H_502_3@
名词解释
@H_502_3@PEM - Privacy Enhanced Mail,打开看文本格式,以”—–BEGIN…”开头,“—–END…”结尾,内容是BASE64编码.
@H_502_3@Apache和*NIX服务器偏向于使用这种编码格式.
@H_502_3@查看PEM格式证书的信息:openssl x509 -in certificate.pem -text -noout
@H_502_3@
@H_502_3@DER - Distinguished Encoding Rules,打开看是二进制格式,不可读.
@H_502_3@Java和Windows服务器偏向于使用这种编码格式.
@H_502_3@查看DER格式证书的信息:openssl x509 -in certificate.der -inform der -text -noout
@H_502_3@
@H_502_3@x509
@H_502_3@X.509是一种非常通用的证书格式。所有的证书都符合ITU-T X.509国际标准,因此(理论上)为一种应用创建的证书可以用于任何其他符合X.509标准的应用。
@H_502_3@x509证书一般会用到三类文,key,csr,crt。
@H_502_3@Key 是私用密钥openssl格式,通常是rsa算法。
@H_502_3@Csr 是证书请求文件,用于申请证书。在制作csr文件的时候,必须使用自己的私钥来签署它,还可以设定一个密钥。
@H_502_3@crt是CA认证后的证书文,(windows下面的,其实是crt),签署人用自己的key给你签署的凭证。
@H_502_3@
@H_502_3@下面是我的实操记录
@H_502_3@
@H_502_3@
利用openssl命令行生成密钥和证书
@H_502_3@其实我们只需要执行下面的这个命令就可以了生成证书和私钥了
@H_502_3@openssl req -new -nodes -x509 -out server.crt -keyout server.key -days 3650 -subj "/C=DE/ST=NRW/L=Earth/O=Random Company/OU=IT/CN=www.random.com/emailAddress=tao_627@aliyun.com"
原文链接:https://www.f2er.com/ubuntu/349879.html
采用下面的命令可以查看PEM格式的证书信息
openssl x509 -in server.pem -text -noout
@H_502_3@
@H_502_3@
编写tls协议的服务器和客户端 @H_502_3@将代码放到GOPATH下面的工程目录下面 @H_502_3@服务器端代码tls_server.go
package main import ( "bufio" "crypto/tls" "log" "net" ) func main() { log.SetFlags(log.Lshortfile) crt,err := tls.LoadX509KeyPair("server.crt","server.key") if err != nil { log.Println(err) return } config := &tls.Config{Certificates: []tls.Certificate{crt}} ln,err := tls.Listen("tcp",":443",config) if err != nil { log.Println(err) return } defer ln.Close() for { conn,err := ln.Accept() if err != nil { log.Println(err) continue } //每个连接对应创建一个协程 go handleConnection(conn) } } //在每个协程中处理接收数据,和发送数据的细节,出现任何错误,立即返回 func handleConnection(conn net.Conn) { defer conn.Close() r := bufio.NewReader(conn) for { msg,err := r.ReadString('\n') if err != nil { log.Println(err) return } println(msg) n,err := conn.Write([]byte("==welcome==\n")) if err != nil { log.Println(n,err) return } } }
客户端代码tls_client.go
package main import ( "crypto/tls" "log" ) func main() { log.SetFlags(log.Lshortfile) conf := &tls.Config{ InsecureSkipVerify: false,} conn,err := tls.Dial("tcp","127.0.0.1:443",conf) if err != nil { log.Println(err) return } defer conn.Close() n,err := conn.Write([]byte("hi,my name is tao_627\n")) if err != nil { log.Println(n,err) return } buf := make([]byte,100) n,err = conn.Read(buf) if err != nil { log.Println(n,err) return } println(string(buf[:n])) }@H_502_3@ 编译 @H_502_3@逐个编译得到client和server的可执行文件tls_client和tls_server @H_502_3@go build tls_client.go @H_502_3@go build tls_server.go @H_502_3@ @H_502_3@ @H_502_3@ 运行 @H_502_3@在两个终端窗口中分别执行 @H_502_3@
sudo ./tls_server
@H_502_3@
./tls_client @H_502_3@ @H_502_3@ @H_502_3@ 注意的问题 @H_502_3@这里编写client代码时候需要注意:InsecureSkipVerify: true @H_502_3@也就是说上面的代码中客户端不对服务端的证书进行验证。 @H_502_3@go实现的Client端默认也是要对服务端传过来的数字证书进行校验的,但客户端提示:这个证书是由不知名CA签发的! @H_502_3@ @H_502_3@ @H_502_3@ 参考文献 [1].https://studygolang.com/articles/10776