此篇文章主要介紹https用Golang產生認證和Golang實現https認證的過程,至於ssl/tls相關的知識點,我在文章末尾會附上我個人覺得對讀者有用的文章。
單向驗證過程:
客戶點包含ca.crt,服務端包含server.key和server.crt;
用戶端:用戶端產生一個隨機數random-client,傳到伺服器端;
服務端:伺服器端接收訊息之後,產生一個隨機數random-server和包含公開金鑰的認證,一起回饋給用戶端;
用戶端:用戶端收到的東西原封不動,加上premaster secret(通過random-client、random-server 經過一定演算法產生的資料),再一次送給伺服器端,這次傳過去的東西是經過服務端的公開金鑰進行加密後資料;
服務端:服務端經過私密金鑰(server.key),進行解密,擷取 premaster secret(協商密鑰過程);
此時用戶端和伺服器端都擁有了三個要素:random-client、random-server和premaster secret,安全通道已經建立,以後的交流都會校檢上面的三個要素通過演算法算出的session key;而雙向認證過程相當於用戶端和服務端反過來再執行認證、加解密、協商一遍。
認證產生方式:
1. openssl工具產生:
第一步,產生ca密鑰和ca認證
openssl genrsa -out ca.key 2048
# 添加 -subj 是為了省去建立請求之後的互動
openssl req -new nodes -key ca.key -subj "//CN=nzh.com" -days 5000 -out ca.crt
第二步,產生server密鑰和認證
openssl genrsa -out server.key 2048
# //CN必須添加,服務端的網域名稱,或者hosts檔案中ip的別名,等同於localhost
openssl req -new -key server.key -subj "//CN=server" -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000
第三步,產生client密鑰和認證
openssl genrsa -out client.key 2048
openssl req -new -key server.key -subj "//CN=client" -out client.csr
echo extendedkeyUsage=clientAuth > ./extfile.cnf
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile ./extfile.cnf -out client.crt -days 5000
2. Golang代碼產生:
第一步,產生認證之前,先構造出認證結構體,並初始化相應的參數;
構造認證請求結構體
第二步,進行認證簽名,如果不是CA認證,則載入待簽名的認證;
載入待簽署憑證
第三步,進行認證簽名,圖中46行和49行主要區別產生CA自我簽署憑證還是產生CA認證簽名;
認證簽名過程
最後產生認證目錄結構如下:
認證目錄結構
Golang代碼實現雙向認證過程:
伺服器端:
雙向認證過程中,只要結構體實現了ServeHTTP結構就相當於實現一個handler;
載入服務端的公開金鑰和私密金鑰用於解密用戶端發送過來的隨機字元;
載入CA認證是為了驗證用戶端的認證是否合格;
服務端代碼
用戶端:
用戶端公開金鑰,私密金鑰和CA認證處理等同於服務端認證處理,然後發送請求,列印傳回值;
用戶端代碼
後續會繼續補充curl命令以及整個實現源碼。