第1步:生成 CA 根证书
???? openssl genrsa -out ca.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes).............+++++..................................................................................................................+++++e is 65537 (0x010001)
???? openssl req -new -x509 -days 3650 -key ca.key -out ca.pem
You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [AU]:cnState or Province Name (full name) [Some-State]:shanghaiLocality Name (eg, city) []:shanghaiOrganization Name (eg, company) [Internet Widgits Pty Ltd]:custerOrganizational Unit Name (eg, section) []:custerCommon Name (e.g. server FQDN or YOUR name) []:localhostEmail Address []:
第2步:用 openssl 生成 ca 和单方 SAN 证书。
筹备默认 OpenSSL 配置文件于当前目录
linux零碎在 : /etc/pki/tls/openssl.cnf
Mac零碎在: /System/Library/OpenSSL/openssl.cnf
1:cp 目录到我的项目目录进行批改设置
cp /System/Library/OpenSSL/openssl.cnf /learn-gin/06.gin-grpc/keys
2:找到 [ CA_default ],关上 copy_extensions = copy
3:找到[ req ],关上 req_extensions = v3_req # The extensions to add to a certificate request
4:找到[ v3_req ],增加 subjectAltName = @alt_names
5:增加新的标签 [ alt_names ] , 和标签字段
[ alt_names ]DNS.1 = localhostDNS.2 = *.custer.fun
这里填入须要退出到 Subject Alternative Names 段落中的域名名称,能够写入多个。
第3步:生成服务端证书
???? openssl genpkey -algorithm RSA -out server.key
........................................................................................+++++.......................................+++++
???? openssl req -new -nodes -key server.key -out server.csr -days 3650 -subj "/C=cn/OU=custer/O=custer/CN=localhost" -config ./openssl.cnf -extensions v3_req
Ignoring -days; not generating a certificate
???? openssl x509 -req -days 3650 -in server.csr -out server.pem -CA ca.pem -CAkey ca.key -CAcreateserial -extfile ./openssl.cnf -extensions v3_req
Signature oksubject=C = cn, OU = custer, O = custer, CN = localhostGetting CA Private Key
server.csr是下面生成的证书申请文件。ca.pem/ca.key是CA证书文件和key,用来对server.csr进行签名认证。这两个文件在之前生成的。
第4步:生成客户端证书
???? openssl genpkey -algorithm RSA -out client.key
........+++++...........+++++
???? openssl req -new -nodes -key client.key -out client.csr -days 3650 -subj "/C=cn/OU=custer/O=custer/CN=localhost" -config ./openssl.cnf -extensions v3_req
Ignoring -days; not generating a certificate
???? openssl x509 -req -days 3650 -in client.csr -out client.pem -CA ca.pem -CAkey ca.key -CAcreateserial -extfile ./openssl.cnf -extensions v3_req
Signature oksubject=C = cn, OU = custer, O = custer, CN = localhostGetting CA Private Key
当初 Go 1.15 以上版本的 GRPC 通信,这样就实现了应用自签CA、Server、Client证书和双向认证
服务端代码
func main() { cert, _ := tls.LoadX509KeyPair("cert/server.pem", "cert/server.key") certPool := x509.NewCertPool() ca, _ := ioutil.ReadFile("cert/ca.pem") certPool.AppendCertsFromPEM(ca) creds := credentials.NewTLS(&tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: certPool, }) rpcServer := grpc.NewServer(grpc.Creds(creds)) services.RegisterProdServiceServer(rpcServer, new(services.ProdService)) listen, _ := net.Listen("tcp", ":8081") rpcServer.Serve(listen)}
客户端代码
func main() { cert, _ := tls.LoadX509KeyPair("cert/client.pem", "cert/client.key") certPool := x509.NewCertPool() ca, _ := ioutil.ReadFile("cert/ca.pem") certPool.AppendCertsFromPEM(ca) creds := credentials.NewTLS(&tls.Config{ Certificates: []tls.Certificate{cert}, ServerName: "localhost", RootCAs: certPool, }) conn, err := grpc.Dial(":8081", grpc.WithTransportCredentials(creds)) if err != nil { log.Fatal(err) } defer conn.Close() prodClient := services.NewProdServiceClient(conn) prodRes, err := prodClient.GetProdStock(context.Background(), &services.ProdRequest{ProdId: 12}) if err != nil { log.Fatal(err) } log.Info(prodRes.ProdStock)}