HTTPS協議、TLS協議、證書認證過程解析


一、HTTPS 協議

HTTPS協議其實就是HTTP over TSL,TSL(Transport Layer Security) 傳輸層安全協議是https協議的核心。

TSL可以理解為SSL (Secure Socket Layer)安全套接字層的后續版本。

TSL握手協議如下圖所示

(注:圖片來源於google圖片)

在建立TCP連接后,開始建立TLS連接。下面抓包分析TLS握手過程,抓包圖片來源於傳輸層安全協議抓包分析之SSL/TLS (自己沒抓到這么完整的包,只能搬運過來了,摔)

(1) client端發起握手請求,會向服務器發送一個ClientHello消息,該消息包括其所支持的SSL/TLS版本、Cipher Suite加密算法列表(告知服務器自己支持哪些加密算法)、sessionID、隨機數等內容。

(2) 服務器收到請求后會向client端發送ServerHello消息,其中包括:

SSL/TLS版本;

session ID,因為是首次連接會新生成一個session id發給client;

Cipher Suite,sever端從Client Hello消息中的Cipher Suite加密算法列表中選擇使用的加密算法;

Radmon 隨機數。

(3) 經過ServerHello消息確定TLS協議版本和選擇加密算法之后,就可以開始發送證書給client端了。證書中包含公鑰、簽名、證書機構等信息。

(4) 服務器向client發送ServerKeyExchange消息,消息中包含了服務器這邊的EC Diffie-Hellman算法相關參數。此消息一般只在選擇使用DHE 和DH_anon等加密算法組合時才會由服務器發出。

 

(5) server端發送ServerHelloDone消息,表明服務器端握手消息已經發送完成了。

(6) client端收到server發來的證書,會去驗證證書,當認為證書可信之后,會向server發送ClientKeyExchange消息,消息中包含客戶端這邊的EC Diffie-Hellman算法相關參數,然后服務器和客戶端都可根據接收到的對方參數和自身參數運算出Premaster secret,為生成會話密鑰做准備。

(7) 此時client端和server端都可以根據之前通信內容計算出Master Secret(加密傳輸所使用的對稱加密秘鑰),client端通過發送此消息告知server端開始使用加密方式發送消息。

(8) 客戶端使用之前握手過程中獲得的服務器隨機數、客戶端隨機數、Premaster secret計算生成會話密鑰master secret,然后使用該會話密鑰加密之前所有收發握手消息的Hash和MAC值,發送給服務器,以驗證加密通信是否可用。服務器將使用相同的方法生成相同的會話密鑰以解密此消息,校驗其中的Hash和MAC值。

(9) 服務器發送ChangeCipherSpec消息,通知客戶端此消息以后服務器會以加密方式發送數據。

(10) sever端使用會話密鑰加密(生成方式與客戶端相同,使用握手過程中獲得的服務器隨機數、客戶端隨機數、Premaster secret計算生成)之前所有收發握手消息的Hash和MAC值,發送給客戶端去校驗。若客戶端服務器都校驗成功,握手階段完成,雙方將按照SSL記錄協議的規范使用協商生成的會話密鑰加密發送數據。

 

二、session ID的復用

根據rfc5246,client和server建立TLS握手過程如下所示:

      Client                                               Server

      ClientHello                  -------->
                                                      ServerHello
                                                     Certificate*
                                               ServerKeyExchange*
                                              CertificateRequest*
                                   <--------      ServerHelloDone
      Certificate*
      ClientKeyExchange
      CertificateVerify*
      [ChangeCipherSpec]
      Finished                     -------->
                                               [ChangeCipherSpec]
                                   <--------             Finished
      Application Data             <------->     Application Data

             Figure 1.  Message flow for a full handshake
* Indicates optional or situation-dependent messages that are not
   always sent.

client在向server發送ClientHello消息的時候,會傳送Session ID給server端,server端收到session Id后會去session緩存中查找是否有相同值。如果找到相同值,則server直接發送一個具有相同session ID的ServerHello消息給client端(此時不必新建Session ID),然后雙方各發一次ChangeCipherSpec消息后直接進入Finished消息互發階段,具體如下圖所示:

      Client                                                Server

      ClientHello                   -------->
                                                       ServerHello
                                                [ChangeCipherSpec]
                                    <--------             Finished
      [ChangeCipherSpec]
      Finished                      -------->
      Application Data              <------->     Application Data

          Figure 2.  Message flow for an abbreviated handshake

client和server通過緩存Session ID可以快速建立TLS握手,但是這么做也有一些弊端,例如:1)負載均衡中,多機之間往往沒有同步 Session 信息,如果客戶端兩次請求沒有落在同一台機器上就無法找到匹配的信息;2)服務端存儲 Session ID 對應的信息不好控制失效時間,太短起不到作用,太長又占用服務端大量資源。而 Session Ticket(會話記錄單)可以解決這些問題,Session Ticket 是用只有服務端知道的安全密鑰加密過的會話信息,最終保存在瀏覽器端。瀏覽器如果在 ClientHello 時帶上了 Session Ticket,只要服務器能成功解密就可以完成快速握手。

三、數字證書的驗證

client端收到server端發過來的證書,首先必須要做的事驗證證書是否可信。如何驗證證書是否可信呢?為了解決這個問題,我們先來了解下證書的組成

從這里面我們能看到證書包含以下內容:

(1) Validity也即有效期,有效期包含生效時間和失效時間,是一個時間區間;

(2) 公鑰信息Subject Public Key Info,包括公鑰的加密算法和公鑰內容;

(3) Fingerprints信息,fingerprints用於驗證證書的完整性,也就是說確保證書沒有被修改過。 其原理就是在發布證書時,發布者根據指紋算法(此處證書使用了SHA-1和SHA-256算法)計算整個證書的hash值(指紋)並和證書放在一起,client在打開證書時,自己也根據指紋算法計算一下證書的hash值(指紋),如果和剛開始的值相同,則說明證書未被修改過;如果hash值不一致,則表明證書內容被篡改過;

(4) 證書的簽名Certificate Signature Value和Certificate Signature Algorithm,對證書簽名所使用的Hash算法和Hash值;

(5) 簽發該證書的CA機構Issuer;

(6) 該證書是簽發給哪個組織/公司信息Subject;

(7) 證書版本Version、證書序列號Serial Number以及Extensions擴展信息等。

如上圖所示,為簽名過程和client端驗證過程。中間方框為一個數字證書,在制作數字證書時,會將證書中的部分內容進行一次Hash得到一個Hash值,然后證書認證機構簡稱CA會使用私鑰將該Hash值加密為Certificate Signature。

當證書發送給Client端之后,Client端首先會使用同樣的Hash算法獲得一個證書的hash值H1。通常瀏覽器和操作系統中集成了CA機構的公鑰信息,瀏覽器收到證書后可以使用這些公鑰解密Certificate Signature內容,得到一個hash值H2。

比較H1和H2,如果值相同,則為可信賴的證書,否則則認為證書不可信。

自己通過openssl生成的自簽發證書只是使用自己的私鑰去加密上圖左側計算出的Hash Value,這個時候client端得到server端發過來的證書之后,仍然會嘗試使用瀏覽器或系統內置的CA機構的公鑰去解密,解密出來的hash值H2當然不可能與H1相同,因此瀏覽器認為該證書不受信任。但是如果我們選擇相信該證書並且繼續訪問該web,訪問並不會出現任何問題,這是因為證書中的公鑰並未加密,使用該公鑰也確實能和server端的私鑰進行TLS握手。

四、證書信任鏈

在證書認證過程中還存在一個證書信任鏈的問題,因為我們從CA機構申請到的證書基本不可能是根證書簽發。還是以百度的證書為例,如下圖所示,百度證書層級為三層,認證過程如下:

(1) 當client端訪問baidu.com的時候,baidu的server會將baidu.com證書發送給client端。

(2) client端的操作系統或者瀏覽器中內置了根證書,但是client端收到baidu.com這個證書后,發現這個證書不是根證書簽發,無法根據本地已有的根證書中的公鑰去驗證baidu.com證書是否可信。

於是client端根據baidu.com證書中的Issuer找到該證書的頒發機構GlobalSign Organization Validation CA - SHA256 - G2,去CA請求baidu.com證書的頒發機構GlobalSign Organization Validation CA - SHA256 - G2的證書。

(3) 請求到證書后發現GlobalSign Organization Validation CA - SHA256 - G2證書是由根證書簽發,而本地剛好有根證書,於是可以利用根證書中的公鑰去驗證(驗證方法見上一節)GlobalSign Organization Validation CA - SHA256 - G2證書,發現驗證通過,於是信任GlobalSign Organization Validation CA - SHA256 - G2證書。

(4) GlobalSign Organization Validation CA - SHA256 - G2證書被信任后,可以使用GlobalSign Organization Validation CA - SHA256 - G2證書中的公鑰去驗證baidu.com證書的可信性。驗證通過,於是信任baidu.com證書。

在這四個步驟中,最開始client端只信任根證書GlobalSign Root CA證書的,然后GlobalSign Root CA證書信任GlobalSign Organization Validation CA - SHA256 - G2證書,而GlobalSign Organization Validation CA - SHA256 - G2證書又信任baidu.com證書,於是client端也信任baidu.com證書。這樣的一個過程就構成了一條信任鏈路,整個證書信任鏈驗證流程如下圖所示。

五、非對稱加解密

非對稱加密包含一個密鑰對:公鑰和私鑰。公鑰可以公開,私鑰必須安全保存。

如上圖所示,數據可以被公鑰加密,加密后的數據只有持有私鑰才能進行解密。同理私鑰加密的數據,也只有對應的公鑰才能解密。

建立HTTPS連接以后,client(瀏覽器)已經獲得server段的公鑰,並且經過TLS協議在握手過程中協商出一個只有雙方知道的對稱密鑰,在后續的數據傳輸過程中都將使用該密鑰進行數據加密傳輸。因為公鑰是公開的,可以下發給所有client端的,這個時候即使其他擁有公鑰的client端截獲到server端發給client端的消息,也無法僅僅憑借公鑰去解密這個消息,因為這個消息加密密鑰是由client和server通過相同算法計算出來,並且添加了隨機數,理論上這個對稱密鑰只有client和server才能知道。

 

參考文檔:

https://tools.ietf.org/html/rfc5246#page-6

http://www.freebuf.com/articles/network/116497.html

https://imququ.com/post/optimize-tls-handshake.html

http://blog.csdn.net/wzzvictory/article/details/9015155


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM