轉載自http://www.itdecent.cn/p/7158568e4867

image.png
1.Client Hello
握手第一步是客戶端向服務端發(fā)送 Client Hello 消息,這個消息里包含了一個客戶端生成的隨機數 Random1、客戶端支持的加密套件(Support Ciphers)和 SSL Version 等信息。通過 Wireshark 抓包,我們可以看到如下信息:

image.png
2.Server Hello
第二步是服務端向客戶端發(fā)送 Server Hello 消息,這個消息會從 Client Hello 傳過來的 Support Ciphers 里確定一份加密套件,這個套件決定了后續(xù)加密和生成摘要時具體使用哪些算法,另外還會生成一份隨機數 Random2。注意,至此客戶端和服務端都擁有了兩個隨機數(Random1+ Random2),這兩個隨機數會在后續(xù)生成對稱秘鑰時用到。

image.png
3.Certificate
這一步是服務端將自己的證書下發(fā)給客戶端,讓客戶端驗證自己的身份,客戶端驗證通過后取出證書中的公鑰。

image.png
Server Key Exchange
如果是DH算法,這里發(fā)送服務器使用的DH參數。RSA算法不需要這一步。

image.png
Certificate Request
Certificate Request 是服務端要求客戶端上報證書,這一步是可選的,對于安全性要求高的場景會用到。
4.Server Hello Done
Server Hello Done 通知客戶端 Server Hello 過程結束。

image.png
5.Certificate Verify
客戶端收到服務端傳來的證書后,先從 CA 驗證該證書的合法性,驗證通過后取出證書中的服務端公鑰,再生成一個隨機數 Random3,再用服務端公鑰非對稱加密 Random3 生成 PreMaster Key。
6.Client Key Exchange
上面客戶端根據服務器傳來的公鑰生成了 PreMaster Key,Client Key Exchange 就是將這個 key 傳給服務端,服務端再用自己的私鑰解出這個 PreMaster Key 得到客戶端生成的 Random3。至此,客戶端和服務端都擁有 Random1 + Random2 + Random3,兩邊再根據同樣的算法就可以生成一份秘鑰,握手結束后的應用層數據都是使用這個秘鑰進行對稱加密。為什么要使用三個隨機數呢?這是因為 SSL/TLS 握手過程的數據都是明文傳輸的,并且多個隨機數種子來生成秘鑰不容易被暴力破解出來。客戶端將 PreMaster Key 傳給服務端的過程如下圖所示:

image.png
7.Change Cipher Spec(Client)
這一步是客戶端通知服務端后面再發(fā)送的消息都會使用前面協(xié)商出來的秘鑰加密了,是一條事件消息。

image.png
8.Encrypted Handshake Message(Client)
這一步對應的是 Client Finish 消息,客戶端將前面的握手消息生成摘要再用協(xié)商好的秘鑰加密,這是客戶端發(fā)出的第一條加密消息。服務端接收后會用秘鑰解密,能解出來說明前面協(xié)商出來的秘鑰是一致的。

image.png
9.Change Cipher Spec(Server)
這一步是服務端通知客戶端后面再發(fā)送的消息都會使用加密,也是一條事件消息。
10.Encrypted Handshake Message(Server)
這一步對應的是 Server Finish 消息,服務端也會將握手過程的消息生成摘要再用秘鑰加密,這是服務端發(fā)出的第一條加密消息??蛻舳私邮蘸髸妹罔€解密,能解出來說明協(xié)商的秘鑰是一致的。

image.png
Application Data
到這里,雙方已安全地協(xié)商出了同一份秘鑰,所有的應用層數據都會用這個秘鑰加密后再通過 TCP 進行可靠傳輸。
雙向驗證
前面提到 Certificate Request 是可選的,下面這張圖展示了雙向驗證的過程:

image.png
握手過程優(yōu)化
Session復用,False Start,Session Ticket等,具體參考https://imququ.com/post/optimize-tls-handshake.html