SSL詳解

SSL

1.總體結構

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

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

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通訊中,服務器和客戶端所使用的加密算法的組合。cookie

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

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

  • 會話校驗(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向量做爲密鑰(預主密鑰)。

密鑰協商抓包

重要信息
    1:指明本身使用的橢圓曲線(通常根據客戶端的拓展中supported_groups中的選擇橢圓曲線算法)。

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

    3:簽名。和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

​ (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) 服務器驗證數據經過,則握手創建成功,開始進行正常的加密數據通訊。

6.3 會話記錄 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) 服務器驗證數據經過,則握手創建成功,開始進行正常的加密數據通訊。

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服務器端用本身的私鑰解密後,會話密鑰協商成功,雙方能夠用同一份會話密鑰來通訊了。

相關文章
相關標籤/搜索