此篇文章主要介紹https用Golang生成證書和Golang實現(xiàn)https認證的過程垦巴,至于ssl/tls相關(guān)的知識點鬼癣,我在文章末尾會附上我個人覺得對讀者有用的文章汪榔。
單向驗證過程:
客戶點包含ca.crt,服務端包含server.key和server.crt驰徊;
客戶端:客戶端生成一個隨機數(shù)random-client庶诡,傳到服務器端惦银;
服務端:服務器端接收消息之后,生成一個隨機數(shù)random-server和包含公鑰的證書末誓,一起回饋給客戶端扯俱;
客戶端:客戶端收到的東西原封不動,加上premaster secret(通過random-client喇澡、random-server?經(jīng)過一定算法生成的數(shù)據(jù))迅栅,再一次送給服務器端,這次傳過去的東西是經(jīng)過服務端的公鑰進行加密后數(shù)據(jù)晴玖;
服務端:服務端經(jīng)過私鑰(server.key)读存,進行解密,獲取?premaster secret(協(xié)商密鑰過程)呕屎;
此時客戶端和服務器端都擁有了三個要素:random-client让簿、random-server和premaster secret,安全通道已經(jīng)建立秀睛,以后的交流都會校檢上面的三個要素通過算法算出的session key尔当;而雙向認證過程相當于客戶端和服務端反過來再執(zhí)行認證、加解密蹂安、協(xié)商一遍椭迎。
證書生成方式:
1. openssl工具生成:
第一步,生成ca密鑰和ca證書
openssl genrsa -out ca.key 2048
# 添加 -subj 是為了省去創(chuàng)建請求之后的交互
openssl req -new nodes -key ca.key -subj "http://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 "http://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 "http://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代碼生成:
第一步,生成證書之前瓷式,先構(gòu)造出證書結(jié)構(gòu)體,并初始化相應的參數(shù)语泽;
第二步贸典,進行證書簽名,如果不是CA證書踱卵,則加載待簽名的證書廊驼;
第三步据过,進行證書簽名,圖中46行和49行主要區(qū)別生成CA自簽名證書還是生成CA證書簽名妒挎;
最后生成證書目錄結(jié)構(gòu)如下:
Golang代碼實現(xiàn)雙向認證過程:
服務器端:
雙向認證過程中绳锅,只要結(jié)構(gòu)體實現(xiàn)了ServeHTTP結(jié)構(gòu)就相當于實現(xiàn)一個handler;
加載服務端的公鑰和私鑰用于解密客戶端發(fā)送過來的隨機字符酝掩;
加載CA證書是為了驗證客戶端的證書是否合格鳞芙;
客戶端:
客戶端公鑰,私鑰和CA證書處理等同于服務端證書處理期虾,然后發(fā)送請求原朝,打印返回值;
后續(xù)會繼續(xù)補充curl命令以及整個實現(xiàn)源碼镶苞。