当前位置: 首页 > news >正文

golang grpc ssl

  1. 无CA场景
    在不考虑CA的场景下呢,client有client.key和client.crt,server有server.key和server.crt,生成方式可以如下:
$ openssl genrsa -out server.key 2048
$ openssl req -new -x509 -days 3650 \-subj "/C=GB/L=China/O=grpc-server/CN=server.grpc.io" \-key server.key -out server.crt$ openssl genrsa -out client.key 2048
$ openssl req -new -x509 -days 3650 \-subj "/C=GB/L=China/O=grpc-client/CN=client.grpc.io" \-key client.key -out client.crt

key对应的是私钥,crt对应的是公钥

如果需要认证呢,首先, 认证分为单向认证和双向认证。
单向认证,client对server的认证,
双向认证,顾名思义是client和server相互认证

那么,对于client认证server来说,需要把server的公钥server.crt传给client,代码如下:

client

func main() {creds, err := credentials.NewClientTLSFromFile("server.crt", "server.grpc.io",)if err != nil {log.Fatal(err)}conn, err := grpc.Dial("localhost:5000",grpc.WithTransportCredentials(creds),)if err != nil {log.Fatal(err)}defer conn.Close()...
}

server

func main() {creds, err := credentials.NewServerTLSFromFile("server.crt", "server.key")if err != nil {log.Fatal(err)}server := grpc.NewServer(grpc.Creds(creds))...
}

那么对于双向认证来说,不仅client需要校验server的公钥server.crt,server同样需要校验client的公钥client.crt

server

func main() {creds, err := credentials.NewServerTLSFromFile("server.crt", "server.key")if err != nil {log.Fatal(err)}server := grpc.NewServer(grpc.Creds(creds))...
}

client

func main() {creds, err := credentials.NewClientTLSFromFile("server.crt", "server.grpc.io",)if err != nil {log.Fatal(err)}conn, err := grpc.Dial("localhost:5000",grpc.WithTransportCredentials(creds),)if err != nil {log.Fatal(err)}defer conn.Close()...
}
  1. 对于有Ca的场景,ca就是一个第三方认证机构,来保证

一般来说,ca的证书生成如下

生成ca私钥

 openssl genrsa -out ca.key 4096

生成CA证书

openssl req -new -x509 -days 365 -subj "/C=GB/L=Beijing/O=github/CN=liuqh.icu" \
-key ca.key -out ca.crt

这样我们就得到了一个ca.crt的ca证书

然后我们如何用ca证书对公钥进行签发呢?一般流程如下

以client端举例

生成私钥

openssl genrsa -out client.key

生成CSR

openssl req -new -subj "/C=GB/L=Beijing/O=github/CN=liuqh.icu"  \
-key client.key -out client.csr 

基于CA签发证书

openssl x509 -req -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 \
-in client.csr -out client.crt

其实这里感觉屏蔽了很多细节。首先我们要知道,基于ca签发证书,本质是通过ca的私钥加密生成了client公钥client.crt,如果server安装了ca.crt,则server就获得了ca的公钥,这样可以对ca签发的client.crt进行解密验证。反向是相同道理的。

那我们再分析几种场景的写法,首先单向认证,client验证server,那么client只需要ca.crt即可验证server了

client

func main() {// Load the server's CA certificatecaCert, err := ioutil.ReadFile("ca.crt")if err != nil {log.Fatalf("failed to load CA certificate: %v", err)}caCertPool := x509.NewCertPool()if ok := caCertPool.AppendCertsFromPEM(caCert); !ok {log.Fatalf("failed to append CA certificate to the certificate pool")}// Create a new TLS configuration with the client's certificate and private keytlsConfig := &tls.Config{ServerName:   nodeConfigSsl.ServerName,RootCAs:      caCertPool,}// Create a new gRPC connection with the TLS transport credentialclientCreds := credentials.NewTLS(tlsConfig)conn, err := grpc.Dial("localhost:12345", grpc.WithTransportCredentials(clientCreds))if err != nil {}// Create a new gRPC client with the connectionclient := NewGreeterClient(conn)// Send a gRPC request to the serverresp, err := client.SayHello(context.Background(), &HelloRequest{Name: "Alice"})if err != nil {log.Fatalf("failed to send request: %v", err)}// Print the server's responsefmt.Println(resp.Message)
}

server

func main() {// Load the server's certificate, private key, and CA certificateserverCert, err := tls.LoadX509KeyPair("server.crt", "server.key")if err != nil {log.Fatalf("failed to load server credentials: %v", err)}// Create a new TLS configuration with the server's certificate and private keytlsConfig := &tls.Config{Certificates: []tls.Certificate{serverCert},}// Create a new gRPC server with the TLS transport credentialserverCreds := credentials.NewTLS(tlsConfig)server := grpc.NewServer(grpc.Creds(serverCreds))// Register the gRPC serverRegisterGreeterServer(server, &greeterServer{})// Listen for incoming connectionslis, err := net.Listen("tcp", ":12345")if err != nil {log.Fatalf("failed to listen: %v", err)}// Start the gRPC serverif err := server.Serve(lis); err != nil {log.Fatalf("failed to serve: %v", err)}
}

第二种双向验证,则需要client传送公钥,但是同时也server也需要传送公钥

server

func main() {// Load the server's certificate, private key, and CA certificateserverCert, err := tls.LoadX509KeyPair("server.crt", "server.key")if err != nil {log.Fatalf("failed to load server credentials: %v", err)}caCert, err := ioutil.ReadFile("ca.crt")if err != nil {log.Fatalf("failed to load CA certificate: %v", err)}caCertPool := x509.NewCertPool()if ok := caCertPool.AppendCertsFromPEM(caCert); !ok {log.Fatalf("failed to append CA certificate to the certificate pool")}// Create a new TLS configuration with the server's certificate and private keytlsConfig := &tls.Config{Certificates: []tls.Certificate{serverCert},ClientAuth:   tls.RequireAndVerifyClientCert,ClientCAs:    caCertPool,}// Create a new gRPC server with the TLS transport credentialserverCreds := credentials.NewTLS(tlsConfig)server := grpc.NewServer(grpc.Creds(serverCreds))// Register the gRPC serverRegisterGreeterServer(server, &greeterServer{})// Listen for incoming connectionslis, err := net.Listen("tcp", ":12345")if err != nil {log.Fatalf("failed to listen: %v", err)}// Start the gRPC serverif err := server.Serve(lis); err != nil {log.Fatalf("failed to serve: %v", err)}
}

client

func main() {// Load the client's certificate and private keyclientCert, err := tls.LoadX509KeyPair("client.crt", "client.key")if err != nil {log.Fatalf("failed to load client credentials: %v", err)}// Load the server's CA certificatecaCert, err := ioutil.ReadFile("ca.crt")if err != nil {log.Fatalf("failed to load CA certificate: %v", err)}caCertPool := x509.NewCertPool()if ok := caCertPool.AppendCertsFromPEM(caCert); !ok {log.Fatalf("failed to append CA certificate to the certificate pool")}// Create a new TLS configuration with the client's certificate and private keytlsConfig := &tls.Config{Certificates: []tls.Certificate{clientCert},ServerName:   ServerName,RootCAs:      caCertPool,}// Create a new gRPC connection with the TLS transport credentialclientCreds := credentials.NewTLS(tlsConfig)conn, err := grpc.Dial("localhost:12345", grpc.WithTransportCredentials(clientCreds))if err != nil {}// Create a new gRPC client with the connectionclient := NewGreeterClient(conn)// Send a gRPC request to the serverresp, err := client.SayHello(context.Background(), &HelloRequest{Name: "Alice"})if err != nil {log.Fatalf("failed to send request: %v", err)}// Print the server's responsefmt.Println(resp.Message)}

非常好的参考文章:
https://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html

http://www.lryc.cn/news/19447.html

相关文章:

  • 华为服务器驱动下载及安装
  • 【Shell】常用命令合集
  • 15- 答题卡识别及分数判定项目 (OpenCV系列) (项目十五)
  • LeetCode 热题 C++ 146. LRU 缓存
  • Java线程池使用与原理解析(线程池优点、使用方法、参数含义及线程池运转机制)
  • mybatis入门配置
  • 黑客入门(超级详细版)
  • Java多线程(三)---synchronized、Lock和volatile
  • JVM-Java内存区域
  • 毕业季,毕业论文查重,paper系列五个免费查重网站推荐
  • 破解票房之谜:为何高票房电影绕不过“猫眼们”?
  • 订单服务-----遇到的问题及解决方案
  • 项目经理如何度量项目?及项目度量指标实例【静说】
  • 我们应该如何优雅的处理 React 中受控与非受控
  • 力扣热题100Day06:20. 有效的括号,21. 合并两个有序链表,22. 括号生成
  • 【Yolov5】保姆级别源码讲解之-推理部分detect.py文件
  • 无重叠区间-力扣435-java贪心策略
  • Python使用VTK对容积超声图像进行体绘制(三维重建)
  • JAVA设计模式之工厂模式讲解
  • 近万字概述L3及以上自动驾驶故障运行和故障安全机制
  • kafka入门到精通
  • es-09模糊查询
  • 57 - 深入解析任务调度
  • CAN总线开发一本全(3) - 微控制器集成的FlexCAN外设
  • Elasticsearch7.8.0版本进阶——段合并
  • Java版贪食蛇游戏
  • 2023年度数学建模竞赛汇总
  • 了解Python语言和版本
  • nvm (node版本管理工具)安装的详细步骤,并解决安装过程中遇到的问题
  • 朴素贝叶斯笔记