SSL詳解


SSL

1.整體結構

SSL是一個介於HTTP協議與TCP之間的一個可選層,其位置大致如下

SSL:(Secure Socket Layer,安全套接字層),為Netscape所研發,用以保障在Internet上數據傳輸之安全,利用數據加密(Encryption)技術,可確保數據在網絡上之傳輸過程中不會被截取。當前版本為3.0。它已被廣泛地用於Web瀏覽器與服務器之間的身份認證和加密數據傳輸。

SSL協議位於TCP/IP協議與各種應用層協議之間,為數據通訊提供安全支持。

SSL協議可分為兩層:

  • SSL握手協議(SSL Handshake Protocol):它建立在SSL記錄協議之上,用於在實際的數據傳輸開始前,通訊雙方進行身份認證、協商加密算法、交換加密密鑰等。
  • SSL記錄協議(SSL Record Protocol):

TLS:(Transport Layer Security,傳輸層安全協議),用於兩個應用程序之間提供保密性和數據完整性。
TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任務組)制定的一種新的協議,它建立在SSL 3.0協議規范之上,是SSL 3.0的后續版本,可以理解為SSL 3.1,它是寫入了 RFC 的。

該協議由兩層組成:

  • TLS 握手協議(TLS Handshake):1) 握手協議;2)密碼規格變更協議;3)警告協議; 4)應用數據協議
  • TLS 記錄協議(TLS Record)較低的層為 TLS 記錄協議,它建立在可靠的傳輸協議(如TCP)之上,為高層協議提供數據封裝、壓縮、加密等基本功能的支持,定義了傳輸的格式;
    • 將消息分割為多個片段;
    • 對每個片段進行壓縮
    • 加上片段編號(防止重放攻擊)計算消息驗證碼MAC值(保證數據完整性),追加在壓縮片段
    • 對稱密碼加密;
    • 加上數據類型、版本號、壓縮后的長度組成的報頭, 就是最終的報文數據;

SSL/TLS協議提供的服務主要有:

  1. 認證用戶和服務器,確保數據發送到正確的客戶機和服務器;
  2. 加密數據以防止數據中途被竊取;
  3. 維護數據的完整性,確保數據在傳輸過程中不被改變

SSL 加密套件

加密套件(CipherList)是指在ssl通信中,服務器和客戶端所使用的加密算法的組合。

  • 密鑰交換 用於決定客戶端與服務器之間在握手的過程中如何認證。使用非對稱加密算法來生成會話密鑰,因為非對稱算法不會將重要數據在通信中傳輸用到的算法包括RSA,Diffie-Hellman,ECDH,PSK等

  • 加密算法 主要是對傳輸的數據進行加密傳輸用的。一般有對稱加和非對稱加密;所以真正要傳輸的數據會使用對稱加密來進行加密。算法名稱后通常會帶有兩個數字,分別表示密鑰的長度和初始向量的長度,比如DES 56/56, RC2 56/128, RC4 128/128, AES 128/128, AES 256/256;

  • 會話校驗(MAC)算法,為了防止握手本身被竄改(這里極容易和證書簽名算法混淆)。算法包括MD5,SHA等

  • 第四部分是PRF(偽隨機數函數),用於生成“master secret”

    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    從其名字可知,它是:
    基於TLS協議的;
    使用ECDHE作為密鑰交換算法ECDHE默認為ECDHE_RSA;
    加密算法是AES(密鑰和初始向量的長度都是256);
    MAC算法(這里就是哈希算法)是SHA。
    

2.TLS與SSL的差異

  1. 版本號 : TLS記錄格式與SSL記錄格式相同,但版本號的值不同,TLS的版本1.0使用的版本號為SSLv3.1。
  2. 報文鑒別碼
  3. 偽隨機函數
  4. 報警代碼
  5. 密文族和客戶證書
  6. certificate_verify和finished消息
  7. 加密計算
  8. 填充

3.TLS主要增強內容

TLS的主要增強內容

TLS的主要目標是使SSL更安全,並使協議的規范更精確和完善。TLS 在SSL v3.0 的基礎上,提供了以下增強內容:

  1. 更安全的MAC算法
  2. 更嚴密的警報
  3. “灰色區域”規范的更明確的定義

4. 密鑰協商過程——TLS握手

由於非對稱加密的速度比較慢,所以它一般用於密鑰交換,雙方通過公鑰算法協商出一份密鑰,然后通過對稱加密來通信,當然,為了保證數據的完整性,在加密前要先經過HMAC的處理。

SSL缺省只進行server端的認證,客戶端的認證是可選的

4.1 客戶端發出請求(ClientHello)

  1. 支持的協議版本,比如TLS 1.0版
  2. 一個客戶端生成的隨機數random_C,稍后用於生成”對話密鑰”
  3. 支持的加密方法,比如RSA公鑰加密(密碼套件)
  4. 支持的壓縮方法
  5. Session id

4.2 服務器回應(SeverHello)

  1. 確認使用的加密通信協議版本,比如TLS 1.0版本。如果瀏覽器與服務器支持的版本不一致,服務器關閉加密通信
  2. 一個服務器生成的隨機數random_S,稍后用於生成”對話密鑰”
  3. 確認使用的加密方法,比如RSA公鑰加密
  4. 服務器證書

:在服務端向客戶端發送的證書中沒有提供足夠的信息(證書公鑰)的時候,如基於 DH 的證書,公鑰不被證書中包含,需要單獨發送,還可以向客戶端發送一個 客戶端握手server_key _exchange,此外,對於非常重要的保密數據,服務端還需要對客戶端進行驗證,以保證數據傳送給了安全的合法的客戶端。服務端可以向客戶端發出 Cerficate Request 消息,要求客戶端發送證書對客戶端的合法性進行驗證。消息包括:

  • 客戶端可以提供的證書類型;
  • 服務器端可以理解的認證機構名稱清單(可以是root CA或者subordinate CA。如果服務器配置了trust keystore, 這里會列出所有在trust keystore中的證書的distinguished name),

最后服務端會發送一個Server Hello Done消息給客戶端,表示Server Hello消息結束了。

4.3 客戶端回應

1.certificate(可選):客戶端證書

2.Client Key Exchange一個隨機數。該隨機數用服務器公鑰加密,防止被竊聽(產生一個48個字節的Key,客戶端使用一些加密算法(例如:RSA, Diffie-Hellman)產生一個48個字節的PreMaster Secret.

**此時客戶端已經獲取全部的計算協商密鑰需要的信息:兩個明文隨機數 random_C 和 random_S 與自己計算產生的 Pre-master,計算得到協商密鑰: **

   master_secret =PRF(pre_master_secret, "master secret", random_C +random_S)

   pre_master_secret就是我們之前傳送的隨機密碼串,”mastersecret”是一串ASCII碼,再加上之前提到的random1和random2。PRF是在規范中約定的偽隨機函數,它將密鑰、ASCII碼標簽、哈希值整合在一起。各有一半的參數分別使用MD5和SHA-1獲取哈希值。這是一種十分明智的做法,即使是想要單單破解相對簡單MD5和SHA-1也不是那么容易的事情。而且這個函數會將返回值傳給自身直至迭代到我們需要的位數
     客戶端得到master_secret后,根據協議約定,我們需要利用PRF生成這個會話中所需要的各種密鑰,稱之為“密鑰塊”(key block)

3.certificate_verify:發送使用客戶端證書給到這一步為止收到和發送的所有握手消息簽名結果(包括master secret)。(向服務器證明自己的確持有客戶端證書私鑰。

4.ChangeCipherSpec 編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發送(ChangeCipherSpec是一個獨立的協議,體現在數據包中就是一個字節的數據,用於告知服務端,客戶端已經切換到之前協商好的加密套件(Cipher Suite)的狀態,准備使用之前協商好的加密套件加密數據並傳輸了

5.客戶端握手結束通知,表示客戶端的握手階段已經結束。這一項同時也是前面發送的所有內容的hash值,用來供服務器校驗(使用HMAC算法計算收到和發送的所有握手消息的摘要,然后通過RFC5246中定義的一個偽函數PRF計算出結果,加密后發送。此數據是為了在正式傳輸應用數據之前對剛剛握手建立起來的加解密通道進行驗證。)

4.4 服務器的最后回應(Server Finish)

  1. 使用私鑰解密加密的Pre-master數據,基於之前交換的兩個明文隨機數 random_C 和 random_S,計算得到協商密鑰:enc_key=Fuc(random_C, random_S, Pre-Master);
  2. 計算之前所有接收信息的 hash 值,然后解密客戶端發送的 encrypted_handshake_message,驗證數據和密鑰正確性;
  3. 發送一個 ChangeCipherSpec(告知客戶端已經切換到協商過的加密套件狀態,准備使用加密套件和 Session Secret加密數據了)
  4. 服務端也會使用 Session Secret 加密一段 Finish 消息發送給客戶端,以驗證之前通過握手建立起來的加解密通道是否成功。

根據之前的握手信息,如果客戶端和服務端都能對Finish信息進行正常加解密且消息正確的被驗證,則說明握手通道已經建立成功,接下來,雙方可以使用上面產生的Session Secret對數據進行加密傳輸了。

4.5 幾個secret

1. PreMaster secret

PreMaster Secret是在客戶端使用RSA或者Diffie-Hellman等加密算法生成的。它將用來跟服務端和客戶端在Hello階段產生的隨機數結合在一起生成 Master Secret。PreMaster secret前兩個字節是TLS的版本號,這是一個比較重要的用來核對握手數據的版本號。服務端需要對密文中解密出來對的PreMaster版本號跟之前Client Hello階段的版本號進行對比,如果版本號變低,則說明被串改,則立即停止發送任何消息

2. Master secret
上面已經提到,由於服務端和客戶端都有一份相同的PreMaster secret和隨機數,這個隨機數將作為后面產生Master secret的種子,結合PreMaster secret,客戶端和服務端將計算出同樣的Master secret。

Master secret是有系列的hash值組成的,它將作為數據加解密相關的secret的 Key Material 的一部分。Key Material最終解析出來的數據如下:

  • write MAC key,就是session secret或者說是session key 用來計算HMAC。
  • Client write MAC key是客戶端發數據的session secret ,
  • Server write MAC secret是服務端發送數據的session key 用來加密消息。
  • MAC(Message Authentication Code),是一個數字簽名,用來驗證數據的完整性,可以檢測到數據是否被串改。

基於ECDHE的SSL


(1):客戶端隨機生成隨機值Ra,計算Pa(x, y) = Ra * Q(x, y),Q(x, y)為全世界公認的某個橢圓曲線算法的基點。將Pa(x, y)發送至服務器。

(2):服務器隨機生成隨機值Rb,計算Pb(x,y) - Rb * Q(x, y)。將Pb(x, y)發送至客戶端。

(3):客戶端計算Sa(x, y) = Ra * Pb(x, y);服務器計算Sb(x, y) = Rb *Pa(x, y)

(4):算法保證了Sa = Sb = S,提取其中的S的x向量作為密鑰(預主密鑰)。

密鑰協商抓包

重要信息

  • 指明自己使用的橢圓曲線(一般根據客戶端的拓展中supported_groups中的選擇橢圓曲線算法)。

  • 公鑰。服務器本地計算一個大數(BIGNUM),乘上曲線的base point,得到一個新的point,這個point就是公鑰,用04+x+y的格式組織起來。04表示unconpressed point,和客戶端的ec_point_formats有關。

  • 簽名。和RSA握手不通,RSA情況下, 只要能值正常協商密鑰,那么必然服務器端有證書對應的私鑰,也間接表明了服務器擁有該證書。DHE/ECDHE不同,證書對應的私鑰並不參與密鑰協商,如果要證明服務器擁有證書,則必然有簽名的操作(就像雙向認證的情況下,客戶端需要發送certificate verify)。被簽名數據從curve type起,至point的y為止。對於TLS1.2,簽名前使用client hello拓展中提供的摘要算法。TLS1.0和TLS1.1,如果本地證書是ECC證書,即若要使用ECDSA簽名,這種摘要算法為SHA1,其他的情況摘要算法為md5+sha1。
    計算摘要之后就調用RSA或者ECDSA進行簽名。注意的是,TLS1.2時要帶上2字節的“Signature Hash Algorithm”。


ECDHE與ECDH的區別

字面少了一個E,E代表了“臨時”,即在握手流程中,作為服務器端,ECDH少了一步計算Pb的過程,Pb用證書中的公鑰代替,而證書對應的私鑰就是Xb。由此可見,使用ECDH密鑰交換算法,服務器必須采用ECC證書;服務器不發送server key exchange報文,因為發送certificate報文時,證書本身就包含了Pb信息。

ECDHE(DHE)算法屬於DH類密鑰交換算法, 私鑰不參與密鑰的協商,故即使私鑰泄漏,客戶端和服務器之間加密的報文都無法被解密,這叫 前向安全(forward secrity)。由於ECDHE每條會話都重新計算一個密鑰(Ra、Rb),故一條會話被解密后,其他會話仍舊安全。

5.應用數據傳輸

在所有的握手階段都完成之后,就可以開始傳送應用數據了。應用數據在傳輸之前,首先要附加上MAC secret,然后再對這個數據包使用write encryption key進行加密。在服務端收到密文之后,使用Client write encryption key進行解密,客戶端收到服務端的數據之后使用Server write encryption key進行解密,然后使用各自的write MAC key對數據的完整性包括是否被串改進行驗證。

6.會話緩存握手過程

6.1概述

為了加快建立握手的速度,減少協議帶來的性能降低和資源消耗(具體分析在后文),TLS 協議有兩類會話緩存機制:

  • 會話標識 session ID: 由服務器端支持,協議中的標准字段,因此基本所有服務器都支持,服務器端保存會話ID以及協商的通信信息,Nginx 中1M 內存約可以保存4000個 session ID 機器相關信息,占用服務器資源較多;
  • 會話記錄 session ticket :t需要服務器和客戶端都支持,屬於一個擴展字段,支持范圍約60%(無可靠統計與來源),將協商的通信信息加密之后發送給客戶端保存,密鑰只有服務器知道,占用服務器資源很少。
  • 二者對比,主要是保存協商信息的位置與方式不同,類似與 http 中的 session 與 cookie。二者都存在的情況下,(nginx 實現)優先使用 session_ticket。

6.2 會話標識 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 信息;
  • 服務器驗證數據通過,則握手建立成功,開始進行正常的加密數據通信。

6.3 會話記錄 session ticket

  • ​如果客戶端和服務器之間曾經建立了連接,服務器會在 new_session_ticket 數據中攜帶加密的 session_ticket 信息,客戶端保存
  • 如果客戶端再次需要和該服務器建立連接,則在 client_hello 中擴展字段 session_ticket 中攜帶加密信息,一起發送給服務器;
  • 服務器解密 sesssion_ticket 數據,如果能夠解密失敗,則按照正常的握手過程進行;
  • 如果解密成功,則返回 change_cipher_spec 與 encrypted_handshake_message 信息,兩個信息作用與 session ID 中類似;
  • 如果客戶端能夠驗證通過服務器加密數據,則客戶端同樣發送 change_cipher_spec與encrypted_handshake_message 信息;
  • 服務器驗證數據通過,則握手建立成功,開始進行正常的加密數據通信。

HMAC

  • 我們假設H是一個將數據塊用一個基本的迭代壓縮函數來加密的散列函數。

  • 我們用B來表示數據塊的字長。(以上說提到的散列函數的分割數據塊字長B=64),用L來表示散列函數的輸出數據字長(MD5中L=16(128位),SHA—1中L=20(160位))。

  • 鑒別密鑰的長度可以是小於等於數據塊字長的任何正整數值。

  • 應用程序中使用的密鑰長度若是比B大,則首先用使用散列函數H作用於它,然后用H輸出的L長度字符串作為在HMAC中實際使用的密鑰。

  • 一般情況下,推薦的最小密鑰K長度是L個字長。(與H的輸出數據長度相等)。

H( K XOR opad, H(K XOR ipad, text))
  • 即為以下步驟:

    • (1) 在密鑰K后面添加0來創建一個子長為B的字符串。(例如,如果K的字長是20字節,B=64字節,則K后會加入44個零字節0x00)

    • (2) 將上一步生成的B字長的字符串與ipad做異或運算。

    • (3) 將數據流text填充至第二步的結果字符串中。

    • (4) 用H作用於第三步生成的數據流。

    • (5) 將第一步生成的B字長字符串與opad做異或運算。

    • (6) 再將第四步的結果填充進第五步的結果中。

    • (7) 用H作用於第六步生成的數據流,輸出最終結果

7.總結

SSL客戶端(也是TCP的客戶端)在TCP鏈接建立之后,發出一個ClientHello來發起握手,這個消息里面包含了自己可實現的算法列表和其它一些需要的消息,SSL的服務器端會回應一個ServerHello,這里面確定了這次通信所需要的算法,然后發過去自己的證書(里面包含了身份和自己的公鑰)。Client在收到這個消息后會生成一個秘密消息,用SSL服務器的公鑰加密后傳過去,SSL服務器端用自己的私鑰解密后,會話密鑰協商成功,雙方可以用同一份會話密鑰來通信了。


免責聲明!

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



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