golang加载双向认证加密的证书key文件

本文介绍了一种用于解密TLS证书的方法,通过使用特定的密码来解密加密的私钥,并提供了详细的步骤说明如何为证书的key增加或移除密码。

证书的key是可以加密保存的,我们需要进行解密加载
func MyLoadX509KeyPair(certFile, keyFile, password string) (tls.Certificate, error) {
   certPEMByte, err := ioutil.ReadFile(certFile)
   if err != nil {
      return tls.Certificate{}, err
   }

   keyPEMByte, err := ioutil.ReadFile(keyFile)
   if err != nil {
      glog.Errorf("read %s failed! err: %s", keyFile, err)
      return tls.Certificate{}, err
   }

   keyPEMBlock, rest := pem.Decode(keyPEMByte)
   if len(rest) > 0 {
      glog.Errorf("Decode key failed!")
      return tls.Certificate{}, errors.Errorf("Decode key failed!")
   }

   if x509.IsEncryptedPEMBlock(keyPEMBlock) {
      keyDePEMByte, err := x509.DecryptPEMBlock(keyPEMBlock, []byte(password))
      if err != nil {
         glog.Errorf("decrypt failed! %s", err)
         return tls.Certificate{}, err
      }

      // 解析出其中的RSA 私钥
      key, err := x509.ParsePKCS1PrivateKey(keyDePEMByte)
      if err != nil {
         glog.Errorf("ParsePKCS1PrivateKey failed! %s", err)
         return tls.Certificate{}, err
      }
      // 编码成新的PEM 结构
      keyNewPemByte := pem.EncodeToMemory(
         &pem.Block{
            Type:  "RSA PRIVATE KEY",
            Bytes: x509.MarshalPKCS1PrivateKey(key),
         },
      )

      return tls.X509KeyPair(certPEMByte, keyNewPemByte)
   } else {
      return tls.X509KeyPair(certPEMByte, keyPEMByte)
   }
}

证书key进行增加密码或者去掉密码的操作方式

1、检测ssl.key 密码是否正确

openssl rsa -text -noout -in server.key
命令输出:
Private-Key: (2048 bit)
modulus:
00:b0:fd:c2:81:60:3f:d2:dc:fe:2d:34:c6:46:1e:
08:72:c3:78:f3:4d:12:16:b9:39:3e:0b:d3:8b:e7:
...

2 . 给server.key 添加密码

openssl rsa -des -in server.key -out encrypt.key
输出:
writing RSA key
Enter PEM pass phrase:  密码
Verifying - Enter PEM pass phrase: 再次输入密码
encrypt.key  这个文件就是加密过的key

3. 去掉密码

encrypt.key        加密KEY
nopassword.key  无加密
#openssl rsa -in encrypt.key -out nopassword.key
writing RSA key
Enter PEM pass phrase:  密码
Verifying - Enter PEM pass phrase: 再次输入密码
在 Go 语言中实现 gRPC 调用的加密,主要通过配置 TLS(Transport Layer Security)来完成。TLS 提供了端到端的数据加密和身份验证机制,确保通信过程中的数据安全性和完整性。 ### 服务端配置 TLS gRPC 服务端需要加载服务器证书和私钥,并创建基于 SSL/TLS 的服务凭据。以下是一个简单的服务端 TLS 配置示例: ```go package main import ( "fmt" "log" "net" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) func main() { // 加载服务器证书和私钥 creds, err := credentials.NewServerTLSFromFile("server.crt", "server.key") if err != nil { log.Fatalf("failed to load server certificates: %v", err) } // 创建 gRPC 服务选项,使用 TLS 凭据 opts := []grpc.ServerOption{ grpc.Creds(creds), } // 创建 gRPC 服务实例 s := grpc.NewServer(opts...) // 注册服务(假设已经定义了一个 HelloService) // pb.RegisterHelloServiceServer(s, &helloService{}) // 监听端口并启动服务 lis, err := net.Listen("tcp", ":1234") if err != nil { log.Fatalf("failed to listen: %v", err) } fmt.Println("Server is running on port 1234 with TLS enabled.") if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } ``` 上述代码中,`credentials.NewServerTLSFromFile` 用于加载服务端的证书和私钥[^1],并通过 `grpc.Creds` 设置为服务的传输凭据。 --- ### 客户端配置 TLS 客户端需要加载信任的根证书以验证服务端的身份,并建立安全连接。以下是客户端的 TLS 实现方式: ```go package main import ( "context" "fmt" "log" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) func main() { // 加载信任的根证书 creds, err := credentials.NewClientTLSFromFile("server.crt", "") if err != nil { log.Fatalf("failed to load root certificate: %v", err) } // 创建安全连接 conn, err := grpc.Dial("localhost:1234", grpc.WithTransportCredentials(creds)) if err != nil { log.Fatalf("failed to connect: %v", err) } defer conn.Close() // 假设已生成客户端 stub // client := pb.NewHelloServiceClient(conn) // reply, err := client.Hello(context.Background(), &pb.HelloString{Value: "world"}) // if err != nil { // log.Fatalf("failed to call Hello: %v", err) // } // fmt.Println(reply.GetValue()) } ``` 在客户端中,`credentials.NewClientTLSFromFile` 用于加载服务端的公钥证书,以便进行身份验证和建立加密通道[^2]。 --- ### 双向认证(mTLS) 如果需要实现双向认证(Mutual TLS),即客户端和服务端都必须提供证书进行身份验证,则需要在服务端和客户端分别配置客户端 CA 证书。 #### 服务端启用 mTLS: ```go // 加载客户端 CA 证书 clientCAs, err := os.ReadFile("client-ca.crt") if err != nil { log.Fatalf("failed to read client CA cert: %v", err) } cp := x509.NewCertPool() if !cp.AppendCertsFromPEM(clientCAs) { log.Fatalf("failed to append client CA certs") } // 配置 TLS 选项,要求客户端提供证书 config := &tls.Config{ ClientCAs: cp, ClientAuth: tls.RequireAndVerifyClientCert, } creds := credentials.NewTLS(config) ``` #### 客户端启用 mTLS: ```go // 加载客户端证书和私钥 cert, err := tls.LoadX509KeyPair("client.crt", "client.key") if err != nil { log.Fatalf("failed to load client certificate: %v", err) } // 加载服务端根证书 rootCAs, err := os.ReadFile("server.crt") if err != nil { log.Fatalf("failed to read server cert: %v", err) } cp := x509.NewCertPool() if !cp.AppendCertsFromPEM(rootCAs) { log.Fatalf("failed to append server certs") } config := &tls.Config{ Certificates: []tls.Certificate{cert}, RootCAs: cp, } creds := credentials.NewTLS(config) ``` 以上代码实现了客户端和服务端之间的双向认证,确保双方身份可信[^2]。 --- ### 使用 SAN 证书支持多个域名 为了使一个证书能够支持多个域名或 IP 地址,可以使用带有 SAN(Subject Alternative Name)扩展的证书。这种证书可以在签发时指定多个 DNS 名称或 IP 地址,适用于多域名部署场景[^2]。 --- ### 总结 - **服务端**:使用 `credentials.NewServerTLSFromFile` 或自定义 `tls.Config` 来加载证书和私钥,并设置为 gRPC 服务的传输凭据。 - **客户端**:使用 `credentials.NewClientTLSFromFile` 或自定义 `tls.Config` 来加载信任的根证书,建立安全连接。 - **双向认证**:服务端需指定客户端 CA 证书并启用 `RequireAndVerifyClientCert`,客户端需加载自己的证书和私钥。 - **SAN 支持**:确保证书包含多个 DNS 或 IP 地址作为替代名称,以适应不同访问路径。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XR风云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值