//第一步,為伺服器端和客戶端準備公鑰、私鑰
# 生成伺服器端私鑰
openssl genrsa -out server.key 1024
# 生成伺服器端公鑰
openssl rsa -in server.key -pubout -out server.pem
//第二步,生成 CA 證照
# 生成 CA 私鑰
openssl genrsa -out ca.key 1024
# X.509 Certificate Signing Request (CSR) Management. ca證照籤名請求
#要求填寫一些資料。Common Name是能訪問的域名
openssl req -new -key ca.key -out ca.csr
# X.509 Certificate Data Management. 生成ca證照
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
//第三步,生成伺服器端證照
# 伺服器端需要向 CA 機構申請簽名證照,在申請簽名證照之前依然是建立自己的 CSR 檔案
openssl req -new -key server.key -out server.csr
# 向自己的 CA 機構申請證照,簽名過程需要 CA 的證照和私鑰參與,最終頒發一個帶有 CA 簽名的證照
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.cr
- 客戶端首先向伺服器端傳送一個 Client Hello 的 SSL 握手資訊。
雖然只有 Client Hello 兩個單詞,但是其訊息體裡面包含了豐富的資訊,我們在 WireShark 上選擇這行記錄,並雙擊,其裡面包含了下面的一些主要資訊。
(1)Handshake Type:Client Hello(握手型別)。
(2)Random(隨機數)和一個時間戳。
(3)客戶端支援的加密協議套裝。
告訴 HTTPS 的伺服器端,客戶端能支援上面這 26 種加密協議套裝上列出的演算法,讓伺服器選擇一個加密協議演算法套裝。
(4)訪問的 Web 伺服器的資訊:
(5)客戶端支援的簽名演算法:
客戶端告訴伺服器其支援 9 種簽名演算法,讓伺服器端自由選擇一個用於後續的加密通訊。
2. HTTPS 伺服器馬上給客戶端回覆 4 條 SSL 握手資訊
HTTPS 伺服器馬上給客戶端回覆了下面這 4 條 SSL 握手資訊。
- Server Hello
- Certificate
- Server Key Exchange Server
- Hello Done
下面具體來看這 4 條由 HTTPS 伺服器端發出的 4 條訊息裡面到底有什麼內容,其會告訴客戶端什麼祕密和資訊呢?
(1)Server Hello SSL 握手資訊
其重點是把客戶端傳送給伺服器端的隨機數又給傳送回去了,而且還生成了伺服器端的 Session ID 併傳送給客戶端,最後告訴客戶端,伺服器端準備選擇TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
作為祕鑰互動的加密協議套裝,該加密協議的套裝名字肯定出現在客戶端傳送給伺服器的支援的 26 個列表中,不信你可以翻回去對比一下。
(2)Certificate
SSL 伺服器證照資訊。在這條 HTTPS 伺服器給客戶端回覆訊息 SSL 握手資訊裡面,其還會把伺服器端的 SSL 證照傳送給客戶端,從上圖的轉包資訊中,我們能清晰地發現伺服器端 SSL 證照的相關資訊,比如,通用名字為 iis-web-01,組織單元為 it 等。
需要注意的是,如果是 SSL 的雙向認證,伺服器端也可以要求客戶端把 SSL 證照傳送給伺服器端(對應的 SSL 握手訊息名稱為:CertificateRequest),這個時候,客戶端就會把其 SSL 證照傳送給伺服器端,從而證明其就是伺服器端信任的客戶端。
(3)Server Key Exchange 握手訊息
HTTPS 伺服器出大招了,告訴了客戶端其將會採用的 EC Diffie-Hellman 演算法進行 HTTPS 伺服器和客戶端的祕鑰交換。具體什麼是 EC Diffie-Hellman 演算法,大家可以自行查閱資料,這裡不再贅述,並提供了 EC Diffie-Hellman 演算法使用到的伺服器端的引數:
- 曲線型別:
named_curve: secp256r1
- 公鑰資訊
- 簽名的演算法:
rsa_pkcs1_sha1
- 簽名的資訊
(4)Server Hello Done 握手資訊
握手資訊列表結束了。
3. HTTPS 客戶端馬上給伺服器端回覆 3 條 SSL 握手資訊
當客戶端收到伺服器端的相關公鑰資訊,SSL 證照以及摘要演算法和摘要資訊後,也不是無動於衷,而是積極的響應了下面的 3 條 SSL 握手資訊。
- Client Key Exchange
- Change Cipher Spec
- Encrypted Handshake Message
那麼這三條 SSL 的握手資訊將會透露出什麼?客戶端到底想告訴伺服器端什麼?讓我們一一分解。
(1)Client Key Exchange 握手資訊
其給伺服器端傳送了一條用伺服器端公鑰加密的資訊,其裡面就包含了預備主密碼(Pre-Master secret),其是由客戶端隨機生成,之後會被用作生成主密碼的種子。根據預備密碼,伺服器和客戶端會計算出相同的主密碼(Master secret),然後根據主密碼生成下面的位元序列(祕鑰素材)。
- 對稱密碼的祕鑰
- 訊息認證碼的祕鑰
- 對稱密碼的 CBC 模式中使用的初始化向量(IV)
需要注意的是,Client 祕鑰交換的方式主要有兩種,一種是通過 RSA 公鑰密碼進行互動,這個時候客戶端會在傳送 ClientKeyExchange 訊息時,將經過加密的預備主密碼一起傳送給伺服器。當使用 Diffie-Hellman 交換祕鑰的時候,客戶端會在傳送 ClientKeyExchange 訊息時,將 Diffie-Hellman 公開值(Pub Key)一起傳送給伺服器,根據這個值,客戶端和伺服器會各自生成預備主密碼,而且更加這個預備主密碼能夠生成相同的對稱主密碼。
(2)Change Cipher Spec 握手資訊
告訴伺服器端,我要切換密碼了!
(3)Encrypted Handshake Message 握手資訊
客戶端發出使用主密碼加密的結束資訊,告訴伺服器端:“祕鑰交換握手協議到此結束”。
4. HTTPS 服務端馬上給客戶端回覆 2 條 SSL 握手資訊
這次輪到伺服器端傳送“Change Cipher Spec”訊息了,伺服器告訴客戶端:“好,現在我也要切換密碼了”。
伺服器端用預備主密碼(Pre-Master secret)計算出的主祕鑰加密了一條資訊,併傳送給客戶端:“好的,祕鑰交換握手協議到此結束”。如果通訊雙方都能把結束訊息解密成功,說明主祕鑰已經交換成功。就可以傳送真正的用主密碼加密的應用資料的資訊了!
5. 服務端用對稱祕鑰把加密過的 HTML 網頁內容傳送給客戶端
伺服器端用成功交換了祕鑰把加密過的 HTML 網頁內容傳送給客戶端,客戶端用以前收到過的對稱祕鑰進行解密,HTTPS 通訊協議圓滿結束。
上面的步驟只是把我當前環境下抓取到的使用 TL S1.2 協議規範進行了 HTTPS 通訊原理和過程的梳理和解釋,在不同的環境下,其通訊過程會有一些差異,比如,如果配置了雙向 SSL 認證,其 SSL 伺服器端還會要求客戶端把客戶端的證照傳送到服務端,從而驗證客戶端是否是可信任的,另外在進行主密碼交換的過程中,也可能採用 RSA 公鑰密碼,而不是 Diffie-Hellman,此時,其 SSL 握手訊息會有所不同,但是整體的流程和互動過程思路基本上保持相同。
上述具體流程如下圖所示