TLS示例開發-golang版本


前言

在進行項目總結的時候,領導提出有關數據安全的問題。總結會議過后,自己查閱了一下資料,發現基於CA的TLS證書認證方案是一個很好的選擇,雖然項目本身也有關於數據安全的處理,但是從遠不及TLS的處理方式。

本文只介紹tls的開發,采用go語言,不會涉及到太多專業的詞語。


制作自簽名證書

初始目錄如下:

grpc-tls/
├── configs
│   ├── cert # 存放證書相關的目錄
├── cmd

CA

為了保證證書的可靠性和有效性,在這里可引入 CA 頒發的根證書的概念。CA就是專門用自己的私鑰給別人進行簽名的單位或者機構,其遵守 X.509 標准,即無論是客戶端還是服務端都是使用CA來簽發證書。

根證書

根證書(root certificate)是屬於根證書頒發機構(CA)的公鑰證書。我們可以通過驗證 CA 的簽名從而信任 CA ,任何人都可以得到 CA 的證書(含公鑰),用以驗證它所簽發的證書(客戶端、服務端)。

它包含了公鑰和密鑰。

CA公鑰

進入cert目錄

openssl genrsa -out ca.key 2048
  • openssl genrsa:生成RSA私鑰,命令的最后一個參數,將指定生成密鑰的位數,如果沒有指定,默認512

CA秘鑰(證書)

openssl req -new -x509 -days 365 -key ca.key -out ca.pem
  • -x509:證書文件格式為x509,目前TLS默認只支持這種格式的證書
  • -days 365:證書有效期1年
  • -out ca.pem:生成的私鑰保存到ca.pem

要填寫的信息:

Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:ca.com
Email Address []:
  • 生成的過程中會要求填一些信息,除了Common Name要取一個容易區分的名字之外,其它都可以隨便填寫,我們在這里將它填為ca.com.

目錄

grpc-tls/
├── configs
│   ├── cert # 存放證書相關的目錄
│   	├── ca.key
│   	└── ca.pem
├── cmd

服務器證書相關

服務器key

# openssl genrsa -out server.key 2048
或者
openssl ecparam -genkey -name secp384r1 -out server.key
  • openssl genrsa:生成RSA私鑰,命令的最后一個參數,將指定生成密鑰的位數,如果沒有指定,默認512
  • openssl ecparam:生成ECC私鑰,命令為橢圓曲線密鑰參數生成及操作,本文中ECC曲線選擇的是secp384r1

生成 CSR(證書申請文件)

CSR 是**Cerificate Signing Request **的英文縮寫,為證書申請文件,在服務器私鑰的基礎上加上一些申請人的屬性信息,比如我是誰,來自哪里,名字叫什么,證書適用於什么場景等的信息,然后帶上進行的簽名,發給CA(私下安全的方式發送),帶上自己簽名的目的是為了防止別人篡改文件。

openssl req -new -key server.key -out server.csr

要填寫的信息:

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:domain.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
  • 生成的過程中會要求填一些信息,除了Common Name要取一個容易區分的名字之外,其它都可以隨便填寫,我們在這里將它填為domain.com;
  • 密碼也是建議填寫;
  • 注意和ca證書的不同。

基於 CA 簽發

使用CA的公鑰對申請文件進行簽名

openssl x509 -req -sha256 -CA ca.pem -CAkey ca.key -CAcreateserial -days 3650 -in server.csr -out server.pem
  • -sha256:生成的證書里面使用sha256作為摘要算法
  • 由於需要往生成的證書里寫入簽名者的信息,所以這里需要ca.pem,因為只有這里有CA的描述信息,ca.key里面只有公鑰的信息。

目錄

grpc-tls/
├── configs
│   ├── cert # 存放證書相關的目錄
│   	├── ca.key
│   	└── ca.pem
│   	├── server.csr
│   	└── server.key
│   	└── server.pem
├── cmd

客戶端證書相關

此生成的證書可用於瀏覽器、java、tomcat、golang等。

客戶端key

openssl ecparam -genkey -name secp384r1 -out client.key

生成CSR(證書申請書)

openssl req -new -key client.key -out client.csr

要填寫的信息:

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:domain.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
  • Common Name要取一個容易區分的名字之外,填為domain.com,和服務器的CSR保持一致;
  • 密碼也是建議填寫;
  • 注意和ca證書的不同。

基於CA簽發

openssl x509 -req -sha256 -CA ca.pem -CAkey ca.key -CAcreateserial -days 3650 -in client.csr -out client.pem

生成客戶端p12格式根證書

該證書用於導入瀏覽器使用。

openssl pkcs12 -export -clcerts -in client.pem -inkey client.key -out client.p12

目錄

grpc-tls/
├── configs
│   ├── cert # 存放證書相關的目錄
│   	├── ca.key
│   	└── ca.pem # 導入瀏覽器使用
│   	├── server.csr
│   	└── server.key
│   	└── server.pem
│   	├── client.csr
│   	└── client.key
│   	└── client.pem
│   	└── client.p12 # 導入瀏覽器使用
├── cmd

證書如何驗證

下面以瀏覽器為例,說明證書的驗證過程:

  • 在TLS握手的過程中,瀏覽器得到了網站的證書(.p12)

  • 打開證書,查看是哪個CA簽名的這個證書(.p12)

  • 在自己信任的CA庫中,找相應CA的證書(ca.pem),

  • 用CA證書里面的公鑰解密網站證書上的簽名,取出網站證書的校驗碼(指紋),然后用CA證書中摘要算法(比如sha256)算出出網站證書的校驗碼,如果校驗碼和簽名中的校驗碼對的上,說明這個證書是合法的,且沒被人篡改過

  • 讀出里面的CN,對於網站的證書,里面一般包含的是域名

  • 檢查里面的域名和自己訪問網站的域名對不對的上,對的上的話,就說明這個證書確實是頒發給這個網站的

  • 到此為止檢查通過

如果瀏覽器發現證書有問題,一般是證書里面的簽名者不是瀏覽器認為值得信任的CA,瀏覽器就會給出警告頁面,這時候需要謹慎,有可能證書被掉包了。如訪問12306網站,由於12306的證書是自己簽的名,並且瀏覽器不認為12306是受信的CA,所以就會給警告,但是一旦你把12306的根證書安裝到了你的瀏覽器中,那么下次就不會警告了,因為你配置了瀏覽器讓它相信12306是一個受信的CA。


在瀏覽器中導入證書

導入證書

  • 詳細步驟百度即可....

  • 個人導入client.p12證書

  • 受信任的根證書頒發機構導入ca.pem證書

修改域名

ca.pem這個證書是發給domain.com的,而不是127.0.0.1,所以在C:\Windows\System32\drivers\etc\hosts添加一記錄:

127.0.0.1   domain.com

測試完成之后記得手動將127.0.0.1 domain.comC:\Windows\System32\drivers\etc\hosts里面刪掉。


golang服務端

目錄

grpc-tls/
├── configs
│   ├── cert # 存放證書相關的目錄
│   	├── ca.key
│   	└── ca.pem # 導入瀏覽器使用
│   	├── server.csr
│   	└── server.key
│   	└── server.pem
│   	├── client.csr
│   	└── client.key
│   	└── client.pem
│   	└── client.p12 # 導入瀏覽器使用
├── cmd
│   ├── main.go

main.go

package main

import (
	"crypto/tls"
	"crypto/x509"
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

func main() {
	router := gin.Default()
	router.GET("/test", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "test",
		})
	})

	// 啟動https方式訪問
	cert, err := tls.LoadX509KeyPair("./configs/cert/server.pem", "./configs/cert/server.key")
	if err != nil {
		log.Fatalf("tls.LoadX509KeyPair err: %v", err)
	}
	certPool := x509.NewCertPool()
	ca, err := ioutil.ReadFile("./configs/cert/ca.pem")
	if err != nil {
		log.Fatalf("ioutil.ReadFile err: %v", err)
	}
	if ok := certPool.AppendCertsFromPEM(ca); !ok {
		log.Fatalf("certPool.AppendCertsFromPEM err")
	}
	ReadTimeout := time.Duration(60) * time.Second
	WriteTimeout := time.Duration(60) * time.Second

	s := &http.Server{
		Addr:          ":8090",
		Handler:        router,
		ReadTimeout:    ReadTimeout,
		WriteTimeout:   WriteTimeout,
		MaxHeaderBytes: 1 << 20,
		TLSConfig:&tls.Config{
			Certificates: []tls.Certificate{cert},
			MinVersion: tls.VersionTLS12,
			ClientAuth:   tls.RequireAndVerifyClientCert,
			ClientCAs:    certPool,
		},
	}

	s.ListenAndServeTLS("./configs/cert/server.pem","./configs/cert/server.key")
}

測試

在瀏覽器輸入https://domain.com:8090/test


參考

SSL/TLS及證書概述

帶入gRPC:TLS 證書認證


免責聲明!

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



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