go語言gRPC系列(二) - 為gRPC添加證書


1. 前言

前情回顧

go語言gRPC系列(一) - gRPC入門

之前我們演示的客戶端和服務端之間是沒有使用證書的,不是很安全。下面演示一下,服務調用之間加入自簽的證書驗證。

生產環境以網上購買的證書為准

2. 生成自簽證書

2.1 MAC生成自簽證書的教程鏈接:

https://www.jianshu.com/p/4cdd29ce424d

2.2 Windows生成自簽證書的教程

  1. 登錄如下鏈接

http://slproweb.com/products/Win32OpenSSL.html

  1. 下載如下的openssl工具

  1. 安裝到某個目錄
  2. 進入安裝目錄的bin文件夾下
  3. 在所在的文件夾打開cmd,並輸入openssl

  1. 然后再執行如下的操作, 生成私鑰文件
  • 會生成一個server.key
genrsa -des3 -out server.key 2048

  1. 創建證書請求
  • 會生成一個server.csr
genrsa -des3 -out server.key 2048

  1. 為了演示簡單,刪除私鑰中的密碼
  • 會生成一個server_no_password.key
rsa -in server.key -out server_no_password.key

  1. 生成公鑰文件
  • 會生成server.crt
x509 -req -days 365 -in server.csr -signkey server_no_password.key -out server.crt


3. 改造服務端使用自簽證書

3.1 復制證書至代碼下

在服務端的目錄下新建一個keys文件夾,並且上之前生成的server_no_password.keyserver.crt復制到目錄下

3.2 改造代碼添加證書認證

改造之前上一節的服務端代碼,具體改造的部分如下標紅的部分

完整的服務端代碼:

package main

import (
	"gomicro-quickstart/grpc_server/service"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"log"
	"net"
)

func main() {
// 1. 引用證書
tls, err := credentials.NewServerTLSFromFile("grpc_server/keys/server.crt", "grpc_server/keys/server_no_password.key")
if err != nil {
	log.Fatal("服務端獲取證書失敗: ", err)
}

// 2. new一個grpc的server,並且加入證書
rpcServer := grpc.NewServer(grpc.Creds(tls))

// 3. 將剛剛我們新建的ProdService注冊進去
service.RegisterProdServiceServer(rpcServer, new(service.ProdService))

// 4. 新建一個listener,以tcp方式監聽8082端口
listener, err := net.Listen("tcp", ":8082")
if err != nil {
	log.Fatal("服務監聽端口失敗", err)
}

// 5. 運行rpcServer,傳入listener
_ = rpcServer.Serve(listener)
}

3.1 運行代碼並查看客戶端的訪問錯誤

運行server服務端

這時候我們同樣運行起來client,發現會報如下的錯,因為我們的服務端使用證書加密了

4. 改造客戶端代碼(單向認證)

4.1 復制公鑰給客戶端

這里為了剛入門演示方便,采用了單向認證。

  1. 在客戶端代碼下新建keys文件夾
  2. 將server.crt復制到keys文件夾下

4.2 改造客戶端代碼

較上一章的代碼的改動如下圖:

完整的客戶端代碼如下:

package main

import (
	"context"
	"fmt"
	"gomicro-quickstart/grpc_client/service"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"log"
)

func main() {
	// 1. 添加公鑰證書的引用, codepie.fun是之前生成證書的時候填寫的common name
	tls, err := credentials.NewClientTLSFromFile("grpc_client/keys/server.crt", "codepie.fun")

	if err != nil {
		log.Fatal("客戶端獲取證書失敗: ", err)
	}

	// 2. 新建連接,端口是服務端開放的8082端口
	conn, err := grpc.Dial(":8082", grpc.WithTransportCredentials(tls))
	if err != nil {
		log.Fatal(err)
	}

	// 退出時關閉鏈接
	defer conn.Close()

	// 3. 調用Product.pb.go中的NewProdServiceClient方法
	productServiceClient := service.NewProdServiceClient(conn)

	// 4. 直接像調用本地方法一樣調用GetProductStock方法
	resp, err := productServiceClient.GetProductStock(context.Background(), &service.ProductRequest{ProdId: 233})
	if err != nil {
		log.Fatal("調用gRPC方法錯誤: ", err)
	}

	fmt.Println("調用gRPC方法成功,ProdStock = ", resp.ProdStock)
}

4.3 運行客戶端查看結果

單向認證成功,服務調用成功


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM