目錄
- Wireshark抓包
- Client Hello
- Server Hello、Certificate、Server Key Exchange、Server Hello Done
- Client 驗證 Server 證書
- Client Key Exchange、Change Cipher Spec、Encrypted Handshake Message
- Server→New Session Ticket
- Server→Change Cipher Spec、Encrypted Handshake Message
- 握手結束
- 加密通信–Application Data
- 重建連接
- 密鑰計算
- 參考文章
Wireshark抓包
首先是 TCP 的三次握手,然後就到 TLS的通信。
Source | Destination | Protocol | Info |
---|---|---|---|
Client |
Server |
TCP |
[SYN] Seq=0 |
Server |
Client |
TCP |
[SYN, ACK] Seq=0 Ack=1 |
Client |
Server |
TCP |
[ACK] Seq=1 Ack=1 |
Client |
Server |
TLSv1.2 |
Client Hello |
Server |
Client |
TLSv1.2 |
Server Hello Certificate Server Key Exchange Server Hello Done |
Client |
Server |
TLSv1.2 |
Client Key Exchange Change Cipher Spec Encrypted Handshake Message |
Server |
Client |
TLSv1.2 |
New Session Ticket Change Cipher Spec Encrypted Handshake Message |
Client |
Server |
TLSv1.2 |
Application Data |
Server |
Client |
TLSv1.2 |
Application Data |
Client Hello
客戶端發起請求,以明文傳輸請求信息,包含版本信息,加密套件候選列表,壓縮算法候選列表,隨機數,擴展字段等信息,相關信息如下:
- 支持的最高
TSL協議
版本version
,從低到高依次SSLv2 < SSLv3 < TLSv1 < TLSv1.1 < TLSv1.2
,當前基本不再使用低於TLSv1
的版本。 - 隨機數
Random
, 用於後續的密鑰的生成。 - 客戶端支持的加密套件
Cipher Suites
列表,每個加密套件對應前面TLS原理中的四個功能的組合:認證算法(身份驗證)、密鑰交換算法KeyExchange(密鑰協商)、對稱加密算法Enc(信息加密)和 信息摘要Mac(完整性校驗)。 - 支持的壓縮算法
Compression Methods
列表,用於後續的信息壓縮傳輸。 - 擴展字段
Extension
,支持協議與算法相關參數以及其它輔助信息等,常見的SNI就屬於擴展字段。
Server Hello、Certificate、Server Key Exchange、Server Hello Done
-
Server Hello
服務端返回墒的信息結果,包括選擇使用的協議版本Version
(TLS 1.2
),選擇的加密套件Cipher Suite
(TLS_ECDHE_RAS_WITH_AES_128_GCM_SHA256
),選擇的壓縮算法Compression Method
(null
)、隨機數Random
等,其中隨機數用於後續的密鑰協商。
-
Certificate
服務器端配置對應的證書鏈,用於身份認證與密鑰交換。
-
Server Key Exchange
Server Hello
中選擇的ECDHE
密鑰交換算法 比RSA
密鑰交換算法多的一個步驟。
-
Server Hello Done
通知客戶端Server Hello
信息發送結束
Client 驗證 Server 證書
客戶端驗證證書的合法性,如果驗證通過纔會進行後續的通信,否則根據錯誤情況做出不同提示和操作,合法性驗證包括如下:
- 證書鏈的可信性
trusted catificate path
(上面Server 端配置的證書鏈) - 證書是否吊銷revocation,有兩類方式離線CRL與在線OCSP,不同的客戶端行爲會不同.
- 有效期expiry date,證書是否在有效時間範圍.
- 域名domain,覈查證書域名是否與當前的訪問域名匹配,匹配規則後續分析.
Client Key Exchange、Change Cipher Spec、Encrypted Handshake Message
-
Client Key Exchange
合法性校驗通過之後,客戶端計算產生隨機數字Pre-master
,並用證書公鑰加密,發送給服務器。
此時客戶端已經獲取全部的計算協商密鑰需要的信息:兩個明文隨機數Random_C
和Random_S
與自己計算產生的Pre-master
,計算得到協商密鑰:enc_key=Fuc(random_C,random_S,Pre-Master)
。 -
Change Cipher Spec
客戶端通知服務器後續的通信都採用協商的通信密鑰和加密算法進行加密通信。 -
Encrypted Handshake Message
結合之前所有通信參數的hash值與其它相關信息生成一段數據,採用協商密鑰session secret與算法進行加密,然後發送給服務器用於數據與握手驗證。
Server:New Session Ticket
爲了加快建立握手的速度,減少協議帶來的性能降低和資源消耗,TLS協議有兩類會話緩存機制:會話標識Session ID 與 會話記錄Session ticket。
-
Session ID
由服務器端支持,協議中的標準字段,因此基本所有服務器都支持,服務器端保存會話ID以及協商的通信信息,Nginx
中1M
內存約可以保存4000個 Session ID
機器相關信息,佔用服務器資源較多。- 如果客戶端和服務器之間曾經建立了連接,服務器會在握手成功後返回 Session ID,並保存對應的通信參數在服務器中。
- 如果客戶端再次需要和該服務器建立連接,則在
Client Hello
中 Session ID 中攜帶記錄的信息,發送給服務器。 - 服務器根據收到的 Session ID 檢索緩存記錄,如果沒有檢索到緩存過期,則按正常的握手過程進行。
- 如果檢索到對應的緩存記錄,則返回
Change Cipher Spec
與Encrypted Handshake Message
信息,兩個信息作用類似,Encrypted Handshake Message
是到當前的通信參數與master_secret
的 Hash值。 - 如果客戶端能夠驗證通過服務器加密數據,則客戶端同樣發送
Change Cipher Spec
與Encrypted Handshake Message
信息。 - 服務器驗證數據通過,則握手建立成功,開始進行正常的加密數據通信。
-
Session ticket
需要服務器和客戶端都支持,屬於一個擴展字段,將協商的通信信息加密之後發送給客戶端保存,密鑰只有服務器知道,佔用服務資源很少。- 如果客戶端和服務器之間曾經建立了連接,服務器會在
New Session Ticket
數據中攜帶加密的Session ticket
信息,客戶端保存。 - 如果客戶端再次需要和該服務器建立連接,則在
Client Hello
中擴展字段Session Ticket
中攜帶加密信息,一起發送給服務器。 - 服務器解密
Session Ticket
數據,如果解密失敗,則按照正常的握手過程進行; - 如果解密成功,則返回
Change Cipher Spec
與Encrypted Handshake Message
信息,兩個信息作用與 Session ID中類似。 - 如果客戶端能夠驗證通過服務器加密數據,則客戶端同樣發送
Change Cipher Spec
與Encrypted Handshake Message
信息。 - 服務器驗證數據通過,則握手建立成功,開始進行正常的加密數據通信。
- 如果客戶端和服務器之間曾經建立了連接,服務器會在
二者對比,主要是保存協議信息的位置與方式不同,類似與 http
的 sessin
與 cookie
。
二者都存在的情況下,(nginx實現)優先使用 Session Ticket
。
Server:Change Cipher Spec、Encrypted Handshake Message
服務器用私鑰解密加密的 Pre-master
數據,基於之前交換的兩個明文隨機數 Random_C
和 Random_S
,計算得到協商密鑰:enc_key=Fuc(random_C,random_S,Pre-Master)
。
計算之前所有接收信息的hash值,然後解密客戶端發送的 Encrypted Handshake Message
,驗證數據和密鑰的正確性。
-
Change Cipher Spec
驗證通過之後,服務器同樣發送Change Cipher Spec
以告知客戶端後續的通信都採用協商的密鑰與算法進行通信。 -
Encrypted Handshake Message
服務器也結合所有當前的通信參數信息生成一段數據並採用協商密鑰Session Secret
與算法加密併發送到客戶端。
握手結束
客戶端計算所有接收信息的 Hash 值,並採用協商密鑰解密 Encrypted Handshake Message
,驗證服務器發送的數據和密鑰,驗證通過則握手完成。
加密通信–Application Data
開始使用協商密鑰與算法進行加密通信。注意:
- 服務器也可以要求驗證客戶端,即雙向認證,可以在
Server Hello
過程要求發送Client Certificate Request
信息,客戶端在Client Key Exchange
過程中先發送Client Certificate
與Certificate Verify Message
信息,證書的驗證方式基本相同,Certificate Verify Message
是採用 Client 的私鑰加密的一段基於已經協商的通信信息得到數據,服務器可以採用對應的公鑰解密並驗證。 - 根據使用的密鑰交換算法的不同,如 ECC 等,協商細節略有不同,總體相似。
Sever Key Exchange
的作用是Server Certificate
沒有攜帶足夠的信息時,發送給客戶端以計算pre-master
,如基於 DH 的證書,公鑰不被證書中包含,需要單獨發送。Change Cipher Spec
實際可用於通知對端改變當前使用的加密通信方式。Alter message
用於指明在握手或通信過程中的狀態改變或錯誤信息,一般告警信息觸發條件是連接關閉,收到不合法的信息,信息解密失敗,用戶取消操作等,收到告警信息之後,通信會被斷開或者由接收方決定是否斷開連接。
重建連接
重建連接(renegotiation
) 即放棄正在使用的 TLS 連接,重新進行 身份認證 和 密鑰協商 的過程,特點是 不需要斷開當前的數據傳輸 就可以重新 身份認證、更新密鑰或算法,因此服務器端存儲和緩存的信息都可以保持。客戶端和服務器都能夠發起重建連接的過程,當前 windows 2000 & XP 與 SSL 2.0不支持。
-
服務器重建連接
服務器端重建連接一般情況是客戶端訪問受保護的數據時發生。基本過程如下:- 客戶端和服務器之間建立了有效 TLS 連接並通信。
- 客戶端訪問受保護的信息。
- 服務器端返回
Hello Request
信息。 - 客戶端收到
Hello Request
信息之後發送Client Hello
信息,開始重新建立連接。
-
客戶端重建連接
客戶端重建連接一般是爲了更新通信密鑰。- 客戶端和服務器之間建立了有效 TLS 連接並通信。
- 客戶端需要更新密鑰,主動發出
Client Hello
信息。 - 服務器端收到
Client Hello
信息之後無法立即識別出該信息非應用數據,因此會提交給下一步處理,處理完之後會返回通知該信息爲要求重建連接。 - 在確定重建連接之前,服務器不會立即停止向客戶端發送數據,可能恰好同時或有緩存數據需要發送給客戶端,但是客戶端不會再發送任何信息給服務器。
- 服務器識別出重建連接請求之後,發送
Server Hello
信息至客戶端。 - 客戶端也同樣無法立即判斷出該信息非應用數據,同樣提交給下一步處理,處理之後會返回通知該信息爲要求重建連接。
- 客戶端和服務器開始新的重建連接的過程。
密鑰計算
上節提到了兩個明文傳輸的隨機數 Random_C
和 Random_S
與通過加密在服務器和客戶端之間交換的 Pre-master
,三個參數作爲密鑰協商的基礎。本節討論說明密鑰協商的基本計算過程以及通信過程中的密鑰使用。
-
計算 Key
涉及參數Random Client
和Random Server
,Pre-master
,Master secret
,key material
, 計算密鑰時,服務器和客戶端都具有這些基本信息,交換方式在上節中有說明,計算流程如下:
- 客戶端採用
RSA
或Diffie-Hellman
等加密算法生成Pre-master
。 Pre-master
結合Random_C
和Random_S
兩個隨機數通過PseudoRandomFunction
(PRF)計算得到Master secret
。Master secret
結合Random_C
和Random_S
兩個隨機數通過迭代計算得到Key material
。
- 客戶端採用
以下爲一些重要的記錄,可以解決部分愛深入研究朋友的疑惑:
- PreMaster secret 前兩個字節是 TLS 的版本號,這是一個比較重要的用來覈對握手數據的版本號,因爲在 Client Hello 階段,客戶端會發送一份加密套件列表和當前支持的 SSL/TLS 的版本號給服務端,而且是使用明文傳送的,如果握手的數據包被破解之後,攻擊者很有可能串改數據包,選擇一個安全性較低的加密套件和版本給服務端,從而對數據進行破解。所以,服務端需要對密文中解密出來對的 PreMaster 版本號跟之前 Client Hello 階段的版本號進行對比,如果版本號變低,則說明被串改,則立即停止發送任何消息。
- 不管是客戶端還是服務器,都需要隨機數,這樣生成的密鑰纔不會每次都一樣。由於 SSL 協議中證書是靜態的,因此十分有必要引入一種隨機因素來保證協商出來的密鑰的隨機性。
對於 RSA 密鑰交換算法來說,pre-master-key 本身就是一個隨機數,再加上 hello 消息中的隨機,三個隨機數通過一個密鑰導出器最終導出一個對稱密鑰。
pre master 的存在在於 SSL 協議不信任每個主機都能產生完全隨機的隨機數,如果隨機數不隨機,那麼 pre master secret 就有可能被猜出來,那麼僅適用 pre master secret 作爲密鑰就不合適了,因此必須引入新的隨機因素,那麼客戶端和服務器加上 pre master secret 三個隨機數一同生成的密鑰就不容易被猜出了,一個僞隨機可能完全不隨機,可是三個僞隨機就十分接近隨機了,每增加一個自由度,隨機性增加的可不是一。
參考文章
以上。