一文讀懂https中密鑰交換協議的原理及流程
一、引言
http與https區別:HTTP 由于是明文傳輸,所以在安全性上存在以下三個風險:
- 竊聽風險,因為明文傳輸,可以直接抓包獲取傳輸的數據,就會導致信息的泄漏。
- 篡改風險,比如強制入垃圾廣告。
- 冒充風險,如搭建一個某平臺的仿真網站,通過DNS欺騙誘導用戶訪問。
HTTPS 在 HTTP 與 TCP 層之間加入了SSL/TLS 協議

HTTPS的通信過程:
1、 TCP的3次握手
2、 TLS的握手
3、 HTTP請求和響應
SSL/TLS 協議基本流程:
1、 客戶端向服務器索要并驗證服務器的公鑰。
2、 雙方協商生產「會話密鑰」。
3、 雙方采用「會話密鑰」進行加密通信。
HTTPS 是如何解決上面的三個風險的呢?
- 混合加密的方式實現信息的機密性,解決了竊聽的風險。
- 摘要算法的方式來實現完整性,它能夠為數據生成獨一無二的「指紋」,指紋用于校驗數據的完整性,解決了篡改的風險。
- 將服務器公鑰放入到數字證書中,解決了冒充的風險。
二、DH密鑰交換協議
Diffie-Hellman(簡稱 DH)算法是WhitefieldDiffie和MartinHellman在1976年公布的一種密鑰交換算法,它是一種建立密鑰的方法,而不是加密方法,所以密鑰必須和其他一種加密算法結合使用。這種密鑰交換技術的目的在于使兩個用戶安全的協商一個會話密碼。Diffie-Hellman密鑰交換算法的有效性依賴于計算離散對數的難度。


基于此背景知識,可以定義Diffie-Hellman密鑰交換算法。該算法描述如下圖2.1:

圖2.1 DH過程圖

現在我們使用到的https通信協議,也就是用到這個協議去協商密鑰,在傳輸前先把數據加密再進行傳輸,達到了會話安全的目的。
應用
應用非常廣泛,在SSH、VPN、Https...都有應用,勘稱現代密碼基石。
拓展
ECC的密鑰交換。https中的ECDHE算法協議。
缺點


圖2.2 DH中間人攻擊
三、RSA算法
RAS算法是由MIT的Ron Rivest,Adi Shamir和Len Adleman在1997年提出并于1978年首次發表的算法,可是說是最早提出的滿足有要求的公鑰算法之一。Rivest-Shamir-Adleman(RSA)算法自其誕生之日起就成為被廣泛接受且被實現的通用公鑰加密方法

四、解析密碼協議在 https 中的應用
4.1https之RSA
RSA密鑰交換算法協議的全過程如下圖3.1.1所示。

3.1.1 RSA密鑰交換協議過程
?RSA 算法來實現密鑰交換,首先將TLS 證書部署服務端,證書文件中包含一對公私鑰,其中公鑰會在 TLS 握手階段傳遞給客戶端,私鑰則一直留在服務端(一定要確保私鑰不能被竊取)
?在 RSA 密鑰協商算法中,客戶端會生成隨機密鑰,并使用服務端的公鑰加密后再傳給服務端。根據非對稱加密算法,公鑰加密的消息僅能通過私鑰解密,這樣服務端解密后,雙方就得到了相同的密鑰,再用它加密應用消息

圖3.1.2 RSA 握手過程包分析
第一次握手
客戶端首先會發一個「Client Hello」消息

消息里面有客戶端使用的TLS 版本號、支持的密碼套件列表,以及生成的隨機數(Client Random),這個隨機數會被服務端保留,它是生成對稱加密密鑰的材料之一。
第二次握手
1 SayHello
當服務端收到客戶端的「ClientHello」消息后,會確認 TLS 版本號是否支持,和從密碼套件列表中選擇一個密碼套件,以及生成隨機數(Server Random)。
接著,返回「Server Hello」消息,消息里面有服務器確認的 TLS 版本號,也給出了隨機數(Server Random),然后從客戶端的密碼套件列表選擇了一個合適的密碼套件。

如上,服務端選擇的密碼套件是: “Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256” 即:握手時密鑰交換算法和簽名算法都是使用 RSA;握手后的通信使用 AES對稱算法,密鑰長度 128 位,分組模式是 GCM;摘要算法 SHA256用于消息認證和產生隨機數; |
2.2 Server Certificate
服務端為了證明自己的身份,會發送「Server Certificate」給客戶端,這個消息里含有數字證書。

1.3 Server Hello Done
服務端發了「ServerHello Done」消息,目的是告訴客戶端,本次服務端側打招呼完畢

第三次握手
1 Client Key Exchange
首先客戶端驗證證書,證書驗證通過后,繼續后面的操作。
客戶端產生一個新的隨機數 (pre-master),并使用服務端的RSA公鑰加密該隨機數,通過「Change Cipher Key Exchange」消息傳給服務端。該隨機數就是后面會話密鑰的重要組成成分之一。

服務端得到客戶端發來的隨機數 (pre-master)后,可用 RSA 私鑰解密。
3.2 ChangeCipher Spec
生成完會話密鑰后,然后客戶端發一個「Change Cipher Spec」,告訴服務端開始使用加密方式發送消息。

3.3 Finished
客戶端再發一個「EncryptedHandshake Message(Finished)」消息,把之前所有發送的數據做個摘要,再用會話密鑰(master secret)加密一下,讓服務器做個驗證,驗證加密通信是否可用,以及驗證之前握手信息是否有被中途篡改過。會話密鑰(master secret)為randomClient+randomServer+ pre-master。

第四次握手
服務器也是同樣的操作,發「ChangeCipher Spec」和「Encrypted Handshake Message」消息,如果雙方都驗證加密和解密沒問題,那么握手正式完成。
最后,就用「會話密鑰」加解密 HTTP 請求和響應了。
RSA密鑰交互的缺陷
使用 RSA 密鑰協商算法的最大問題是不支持前向保密。因為客戶端傳遞隨機數(用于生成對稱加密密鑰的條件之一)給服務端時使用的是公鑰加密的,服務端收到到后,會用私鑰解密得到隨機數。所以一旦服務端的私鑰泄漏了,過去被第三方截獲的所有 TLS 通訊密文都會被破解。
為了解決這一問題,于是就有了 ECDHE 密鑰協商算法
4.2 https之ECDHE
ECDHE密鑰交換協議算法的全過程如下圖3.2.1所示。與RSA(圖3.1.1)密鑰交換協議有一定的區別,服務端不會去初始話密碼系統。

圖3.2.1 ECDHE流程圖
DH 密鑰交換過程中,即使第三方截獲了 TLS 握手階段傳遞的公鑰,在不知道的私鑰的情況下,也是無法計算出密鑰的,而且每一次對稱加密密鑰都是實時生成的,實現前向保密。
現在使用的交互協議是ECDHE, 即ECC + DH+E (即基于橢圓曲線的一次一密密鑰交換協議, E:ephemeral)

圖3.2.2 ECDHE會話網絡包
第一次握手
客戶端首先會發一個「ClientHello」消息,消息里面有客戶端使用的 TLS 版本號、支持的密碼套件列表,以及生成的隨機數(Client Random)。

第二次握手
1 ServerHello
服務端收到客戶端的「打招呼」,相應客服端,會返回「Server Hello」消息,消息面有服務器確認的 TLS 版本號,也給出了一個隨機數(Server Random),然后從客戶端的密碼套件列表選擇了一個合適的密碼套件。

如上,服務端選擇的密碼套件是: “TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256” 即:密鑰協商算法使用 ECDHE;簽名算法使用 RSA;握手后的通信使用 AES 對稱算法,密鑰長度 128 位,分組模式是 GCM;摘要算法使用 SHA256; |
2 Certificate
接著,服務端為了證明自己的身份,發送「Certificate」消息,會把證書也發給客戶端。

3 ServerKey Exchange

這個過程服務器做了三件事:
- 選擇了名為named_curve 的橢圓曲線,選好了橢圓曲線相當于橢圓曲線基點 G 也定好了,這些都會公開給客戶端;
- 生成隨機數作為服務端橢圓曲線的私鑰,保留到本地;
- 根據基點 G 和私鑰計算出服務端的橢圓曲線公鑰,這個會公開給客戶端。
為了保證這個橢圓曲線的公鑰不被第三方篡改,服務端會用 RSA 簽名算法給服務端的橢圓曲線公鑰做個簽名。
4 ServerHello Done
隨后,就是「Server HelloDone」消息,服務端跟客戶端表明:“這些就是我提供的信息,打招呼完畢”

至此,TLS 兩次握手就已經完成了,目前客戶端和服務端通過明文共享了這幾個信息:Client Random、Server Random 、使用的橢圓曲線、橢圓曲線基點 G、服務端橢圓曲線的公鑰,這幾個信息很重要,是后續生成會話密鑰的材料
第三次握手
1 KeyExchange
客戶端收到了服務端的證書后,首先要校驗證書是否合法,如果證書合法,那么服務端的身份就是沒問題的。確認無誤后,就可以繼續往下走。
客戶端會生成一個隨機數作為客戶端橢圓曲線的私鑰,然后再根據服務端前面給的信息,生成客戶端的橢圓曲線公鑰,然后用「Client Key Exchange」消息發給服務端

至此,雙方都有對方的橢圓曲線公鑰、自己的橢圓曲線私鑰、橢圓曲線基點 G。于是,雙方都就計算出點(x,y),其中 x 坐標值雙方都是一樣的,前面說 ECDHE 算法時候,說 x 是會話密鑰,但實際應用中,x 還不是最終的會話密鑰。
TLS 握手階段,客戶端和服務端都會生成了一個隨機數傳遞給對方
最終的會話密鑰,就是用「客戶端隨機數 + 服務端隨機數 + x(ECDHE 算法算出的共享密鑰) 」三個材料生成的。
之所以需要3個,是因為客戶端或服務器「偽隨機數」的可靠性不可信,為了保證真正的完全隨機,把三個不可靠的隨機數混合起來,那么「隨機」的程度就非常高了。
2 ChangeCipher Spec
算好會話密鑰后,客戶端會發一個「Change Cipher Spec」消息,告訴服務端后續改用對稱算法加密通信。

3 EncryptedHandshake Message
接著,客戶端會發「EncryptedHandshake Message」消息,把之前發送的數據做一個摘要,再用對稱密鑰加密一下,讓服務端做個驗證,驗證下本次生成的對稱密鑰是否可以正常使用。

第四次握手
最后,服務端也會有一個同樣的操作,發「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果雙方都驗證加密和解密沒問題,那么握手正式完成。于是,就可以正常收發加密的 HTTP 請求和響應了。
五、RSA協議和ECDHE協議對比分析
5.1RSA 和 ECDHE 握手過程的區別
- RSA 密鑰協商算法「不支持」前向保密,ECDHE 密鑰協商算法「支持」前向保密;
- 使用了 RSA 密鑰協商算法,TLS 完成四次握手后,才能進行應用數據傳輸,而對于 ECDHE 算法,客戶端可以不用等服務端的最后一次 TLS 握手,就可以提前發出加密的 HTTP 數據,節省了一個消息的往返時間;
- 使用 ECDHE, 在 TLS 第 2 次握手中,會出現服務器端發出的「Server Key Exchange」消息,而 RSA 握手過程沒有該消息;
5.2為什么RSA模式下知道證書私鑰可以解密流量包?
由前面的流程可以看到,RSA密鑰交換過程中,是客服端選擇一個隨機數作為會話密鑰,然后用服務端證書的公鑰加密,加密后的密文傳輸過去,然后服務端用私鑰解密。
表面看是實現了密鑰交換,但實際上,會話密鑰還是在網絡中進行了傳輸,因此每次數據表中都可以得到。得到后如果有服務端的證書和私鑰,就可以解密了。
因此也稱此為不具有前向安全性,只要服務端不換證書,那么所有證書范圍內的會話都可以進行解密。對于旁路監聽流量,擁有全量數據包的情況下,是可以全部解密的
5.3為什么ECDHE模式不可以解密流量包?
由前面的流程可以看到,與RSA密鑰協商算法不同的是,ECDHE在進行會話密鑰協商時,第2和第3次握手中,都是服務端與客服端生成自己的臨時公私鑰對,在網絡中交換時,僅僅只是傳輸了公鑰,會話密鑰完全在本地計算,而且雙方的私鑰也未暴露在網絡中,所以只是抓包和知道證書與私鑰,也是不能恢復出會話密鑰的。
參考文獻
[1] William Stallings. 密碼編碼學與網絡安全-原理與實踐(第六版)[M].電子工業出版社, 2003.