HTTPS協議詳解(四):TLS/SSL握手過程
1、握手與密鑰協商過程
基於RSA握手和密鑰交換的客戶端驗證伺服器為示例詳解TLS/SSL握手過程
再看一張手繪時序圖
(1).client_hello
客戶端發起請求,以明文傳輸請求信息,包含版本信息,加密套件候選列表,壓縮演算法候選列表,隨機數,擴展欄位等信息,相關信息如下:
? 支持的最高TSL協議版本version,從低到高依次 SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,當前基本不再使用低於 TLSv1 的版本;
? 客戶端支持的加密套件 cipher suites 列表, 每個加密套件對應前面 TLS 原理中的四個功能的組合:認證演算法 Au (身份驗證)、密鑰交換演算法 KeyExchange(密鑰協商)、對稱加密演算法 Enc (信息加密)和信息摘要 Mac(完整性校驗);
? 支持的壓縮演算法 compression methods 列表,用於後續的信息壓縮傳輸;
? 隨機數 random_C,用於後續的密鑰的生成;
? 擴展欄位 extensions,支持協議與演算法的相關參數以及其它輔助信息等,常見的 SNI 就屬於擴展欄位,後續單獨討論該欄位作用。
(2).server_hello+server_certificate+sever_hello_done
? server_hello, 服務端返回協商的信息結果,包括選擇使用的協議版本 version,選擇的加密套件 cipher suite,選擇的壓縮演算法 compression method、隨機數 random_S 等,其中隨機數用於後續的密鑰協商;
? server_certificates, 伺服器端配置對應的證書鏈,用於身份驗證與密鑰交換;
? server_hello_done,通知客戶端 server_hello 信息發送結束;
(3).證書校驗
客戶端驗證證書的合法性,如果驗證通過才會進行後續通信,否則根據錯誤情況不同做出提示和操作,合法性驗證包括如下:
? [證書鏈]的可信性 trusted certificate path,方法如前文所述;
? 證書是否吊銷 revocation,有兩類方式離線 CRL 與在線 OCSP,不同的客戶端行為會不同;
? 有效期 expiry date,證書是否在有效時間範圍;
? 域名 domain,核查證書域名是否與當前的訪問域名匹配,匹配規則後續分析;
(4).client_key_exchange+change_cipher_spec+encrypted_handshake_message
(a) client_key_exchange,合法性驗證通過之後,客戶端計算產生隨機數字 Pre-master,並用證書公鑰加密,發送給伺服器;
(b) 此時客戶端已經獲取全部的計算協商密鑰需要的信息:兩個明文隨機數 random_C 和 random_S 與自己計算產生的 Pre-master,計算得到協商密鑰;
enc_key=Fuc(random_C, random_S, Pre-Master)
(c) change_cipher_spec,客戶端通知伺服器後續的通信都採用協商的通信密鑰和加密演算法進行加密通信;
(d) encrypted_handshake_message,結合之前所有通信參數的 hash 值與其它相關信息生成一段數據,採用協商密鑰 session secret 與演算法進行加密,然後發送給伺服器用於數據與握手驗證;
(5).change_cipher_spec+encrypted_handshake_message
(a) 伺服器用私鑰解密加密的 Pre-master 數據,基於之前交換的兩個明文隨機數 random_C 和 random_S,計算得到協商密鑰:enc_key=Fuc(random_C, random_S, Pre-Master);
(b) 計算之前所有接收信息的 hash 值,然後解密客戶端發送的 encrypted_handshake_message,驗證數據和密鑰正確性;
(c) change_cipher_spec, 驗證通過之後,伺服器同樣發送 change_cipher_spec 以告知客戶端後續的通信都採用協商的密鑰與演算法進行加密通信;
(d) encrypted_handshake_message, 伺服器也結合所有當前的通信參數信息生成一段數據並採用協商密鑰 session secret 與演算法加密並發送到客戶端;
(6).握手結束
客戶端計算所有接收信息的 hash 值,並採用協商密鑰解密 encrypted_handshake_message,驗證伺服器發送的數據和密鑰,驗證通過則握手完成;
(7).加密通信
開始使用協商密鑰與演算法進行加密通信。
注意:
(a) 伺服器也可以要求驗證客戶端,即雙向認證,可以在過程2要發送 client_certificate_request 信息,客戶端在過程4中先發送 client_certificate與certificate_verify_message 信息,證書的驗證方式基本相同,certificate_verify_message 是採用client的私鑰加密的一段基於已經協商的通信信息得到數據,伺服器可以採用對應的公鑰解密並驗證;
(b) 根據使用的密鑰交換演算法的不同,如 ECC 等,協商細節略有不同,總體相似;
(c) sever key exchange 的作用是 server certificate 沒有攜帶足夠的信息時,發送給客戶端以計算 pre-master,如基於 DH 的證書,公鑰不被證書中包含,需要單獨發送;
(d) change cipher spec 實際可用於通知對端改版當前使用的加密通信方式,當前沒有深入解析;
(e) alter message 用於指明在握手或通信過程中的狀態改變或錯誤信息,一般告警信息觸發條件是連接關閉,收到不合法的信息,信息解密失敗,用戶取消操作等,收到告警信息之後,通信會被斷開或者由接收方決定是否斷開連接。
2、會話緩存握手過程
為了加快建立握手的速度,減少協議帶來的性能降低和資源消耗(具體分析在後文),TLS 協議有兩類會話緩存機制:會話標識 session ID 與會話記錄 session ticket。
session ID 由伺服器端支持,協議中的標準欄位,因此基本所有伺服器都支持,伺服器端保存會話ID以及協商的通信信息,Nginx 中1M 內存約可以保存4000個 session ID 機器相關信息,佔用伺服器資源較多;
session ticket 需要伺服器和客戶端都支持,屬於一個擴展欄位,支持範圍約60%(無可靠統計與來源),將協商的通信信息加密之後發送給客戶端保存,密鑰只有伺服器知道,佔用伺服器資源很少。
二者對比,主要是保存協商信息的位置與方式不同,類似與 http 中的 session 與 cookie。
二者都存在的情況下,(nginx 實現)優先使用 session_ticket。
握手過程如下圖:
注意:雖然握手過程有1.5個來回,但是最後客戶端向伺服器發送的第一條應用數據不需要等待伺服器返回的信息,因此握手延時是1*RTT。
(1).會話標識 session ID
(a) 如果客戶端和伺服器之間曾經建立了連接,伺服器會在握手成功後返回 session ID,並保存對應的通信參數在伺服器中;
(b) 如果客戶端再次需要和該伺服器建立連接,則在 client_hello 中 session ID 中攜帶記錄的信息,發送給伺服器;
(c) 伺服器根據收到的 session ID 檢索緩存記錄,如果沒有檢索到貨緩存過期,則按照正常的握手過程進行;
(d) 如果檢索到對應的緩存記錄,則返回 change_cipher_spec 與 encrypted_handshake_message 信息,兩個信息作用類似,encrypted_handshake_message 是到當前的通信參數與 master_secret的hash 值;
(f) 如果客戶端能夠驗證通過伺服器加密數據,則客戶端同樣發送 change_cipher_spec 與 encrypted_handshake_message 信息;
(g) 伺服器驗證數據通過,則握手建立成功,開始進行正常的加密數據通信。
(2).會話記錄 session ticket
(a) 如果客戶端和伺服器之間曾經建立了連接,伺服器會在 new_session_ticket 數據中攜帶加密的 session_ticket 信息,客戶端保存;
(b) 如果客戶端再次需要和該伺服器建立連接,則在 client_hello 中擴展欄位 session_ticket 中攜帶加密信息,一起發送給伺服器;
(c) 伺服器解密 sesssion_ticket 數據,如果能夠解密失敗,則按照正常的握手過程進行;
(d) 如果解密成功,則返回 change_cipher_spec 與 encrypted_handshake_message 信息,兩個信息作用與 session ID 中類似;
(f)如果客戶端能夠驗證通過伺服器加密數據,則客戶端同樣發送 change_cipher_spec與encrypted_handshake_message 信息;
(g) 伺服器驗證數據通過,則握手建立成功,開始進行正常的加密數據通信。
3、重建連接
重建連接 renegotiation 即放棄正在使用的 TLS 連接,從新進行身份認證和密鑰協商的過程,特點是不需要斷開當前的數據傳輸就可以重新身份認證、更新密鑰或演算法,因此伺服器端存儲和緩存的信息都可以保持。客戶端和伺服器都能夠發起重建連接的過程,當前 windows 2000 & XP 與 SSL 2.0不支持。
(1).伺服器重建連接
伺服器端重建連接一般情況是客戶端訪問受保護的數據時發生。基本過程如下:
(a) 客戶端和伺服器之間建立了有效 TLS 連接並通信;
(b) 客戶端訪問受保護的信息;
(c) 伺服器端返回 hello_request 信息;
(d) 客戶端收到 hello_request 信息之後發送 client_hello 信息,開始重新建立連接。
(2).客戶端重建連接
客戶端重建連接一般是為了更新通信密鑰。
(a) 客戶端和伺服器之間建立了有效 TLS 連接並通信;
(b) 客戶端需要更新密鑰,主動發出 client_hello 信息;
(c) 伺服器端收到 client_hello 信息之後無法立即識別出該信息非應用數據,因此會提交給下一步處理,處理完之後會返回通知該信息為要求重建連接;
(d) 在確定重建連接之前,伺服器不會立即停止向客戶端發送數據,可能恰好同時或有緩存數據需要發送給客戶端,但是客戶端不會再發送任何信息給伺服器;
(e) 伺服器識別出重建連接請求之後,發送 server_hello 信息至客戶端;
(f) 客戶端也同樣無法立即判斷出該信息非應用數據,同樣提交給下一步處理,處理之後會返回通知該信息為要求重建連接;
(g) 客戶端和伺服器開始新的重建連接的過程。
4、密鑰計算
上節提到了兩個明文傳輸的隨機數 random_C 和 random_S 與通過加密在伺服器和客戶端之間交換的 Pre-master,三個參數作為密鑰協商的基礎。本節討論說明密鑰協商的基本計算過程以及通信過程中的密鑰使用。
另一篇文章,容易理解一下:掃盲 HTTPS 和 SSL/TLS 協議[3]:密鑰交換(密鑰協商)演算法及其原理
(1).計算 Key
涉及參數 random client 和 random server, Pre-master, Master secret, key material, 計算密鑰時,伺服器和客戶端都具有這些基本信息,交換方式在上節中有說明,計算流程如下:
(a) 客戶端採用 RSA 或 Diffie-Hellman 等加密演算法生成 Pre-master;
(b) Pre-master 結合 random client 和 random server 兩個隨機數通過 PseudoRandomFunction(PRF)計算得到 Master secret;
(c) Master secret 結合 random client 和 random server 兩個隨機數通過迭代計算得到 Key material;
以下為一些重要的記錄,可以解決部分愛深入研究朋友的疑惑,copy的材料,分享給大家:
(a) PreMaster secret 前兩個位元組是 TLS 的版本號,這是一個比較重要的用來核對握手數據的版本號,因為在 Client Hello 階段,客戶端會發送一份加密套件列表和當前支持的 SSL/TLS 的版本號給服務端,而且是使用明文傳送的,如果握手的數據包被破解之後,攻擊者很有可能串改數據包,選擇一個安全性較低的加密套件和版本給服務端,從而對數據進行破解。所以,服務端需要對密文中解密出來對的 PreMaster 版本號跟之前 Client Hello 階段的版本號進行對比,如果版本號變低,則說明被串改,則立即停止發送任何消息。(copy)
(b) 不管是客戶端還是伺服器,都需要隨機數,這樣生成的密鑰才不會每次都一樣。由於 SSL 協議中證書是靜態的,因此十分有必要引入一種隨機因素來保證協商出來的密鑰的隨機性。
對於 RSA 密鑰交換演算法來說,pre-master-key 本身就是一個隨機數,再加上 hello 消息中的隨機,三個隨機數通過一個密鑰導出器最終導出一個對稱密鑰。
pre master 的存在在於 SSL 協議不信任每個主機都能產生完全隨機的隨機數,如果隨機數不隨機,那麼 pre master secret 就有可能被猜出來,那麼僅適用 pre master secret 作為密鑰就不合適了,因此必須引入新的隨機因素,那麼客戶端和伺服器加上 pre master secret 三個隨機數一同生成的密鑰就不容易被猜出了,一個偽隨機可能完全不隨機,可是三個偽隨機就十分接近隨機了,每增加一個自由度,隨機性增加的可不是一。
(2).密鑰使用
Key 經過12輪迭代計算會獲取到12個 hash 值,分組成為6個元素,列表如下:
(a) mac key、encryption key 和 IV 是一組加密元素,分別被客戶端和伺服器使用,但是這兩組元素都被兩邊同時獲取;
(b) 客戶端使用 client 組元素加密數據,伺服器使用 client 元素解密;伺服器使用 server 元素加密,client 使用 server 元素解密;
(c) 雙向通信的不同方向使用的密鑰不同,破解通信至少需要破解兩次;
(d) encryption key 用於對稱加密數據;
(e) IV 作為很多加密演算法的初始化向量使用,具體可以研究對稱加密演算法;
(f) Mac key 用於數據的完整性校驗;
(3).數據加密通信過程
(a) 對應用層數據進行分片成合適的 block;
(b) 為分片數據編號,防止重放攻擊;
(c) 使用協商的壓縮演算法壓縮數據;
(d) 計算 MAC 值和壓縮數據組成傳輸數據;
(e) 使用 client encryption key 加密數據,發送給伺服器 server;
(f) server 收到數據之後使用 client encrytion key 解密,校驗數據,解壓縮數據,重新組裝。
註:MAC值的計算包括兩個 Hash 值:client Mac key 和 Hash (編號、包類型、長度、壓縮數據)。
5、抓包分析
關於抓包不再詳細分析,按照前面的分析,基本的情況都能夠匹配,根據平常定位問題的過程,個人提些認為需要注意的地方:
(1).抓包 HTTP 通信,能夠清晰的看到通信的頭部和信息的明文,但是 HTTPS 是加密通信,無法看到 HTTP 協議的相關頭部和數據的明文信息,
(2).抓包 HTTPS 通信主要包括三個過程:TCP 建立連接、TLS 握手、TLS 加密通信,主要分析 HTTPS 通信的握手建立和狀態等信息。
(3).client_hello
根據 version 信息能夠知道客戶端支持的最高的協議版本號,如果是 SSL 3.0 或 TLS 1.0 等低版本協議,非常注意可能因為版本低引起一些握手失敗的情況;
根據 extension 欄位中的 server_name 欄位判斷是否支持SNI,存在則支持,否則不支持,對於定位握手失敗或證書返回錯誤非常有用;
會話標識 session ID 是標準協議部分,如果沒有建立過連接則對應值為空,不為空則說明之前建立過對應的連接並緩存;
會話記錄 session ticke t是擴展協議部分,存在該欄位說明協議支持 sesssion ticket,否則不支持,存在且值為空,說明之前未建立並緩存連接,存在且值不為空,說明有緩存連接。
(4).server_hello
根據 TLS version 欄位能夠推測出伺服器支持的協議的最高版本,版本不同可能造成握手失敗;
基於 cipher_suite 信息判斷出伺服器優先支持的加密協議;
(5).ceritficate
伺服器配置並返回的證書鏈,根據證書信息並於伺服器配置文件對比,判斷請求與期望是否一致,如果不一致,是否返回的默認證書。
(6).alert
告警信息 alert 會說明建立連接失敗的原因即告警類型,對於定位問題非常重要。
---------------------
作者:hherima
來源:CSDN
原文:https://blog.csdn.net/hherima/article/details/52469674
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
加入群聊
微信群關聯的知識星球 群友通訊錄免費加入免費共享 安全行業資料、法律法規、等保相關標準、行業標準及建設方案等,為了【天億網路安全】微信群管理,想進群的朋友先加我好友,我拉你們進群,微信二維碼如下:
—THE END—
朋友都在看
天億網路安全
【歡迎收藏分享到朋友圈,讓更多朋友了解網路安全,分享也是一種美德!】