《HTTPS權威指南》-協議學習筆記

《HTTPS權威指南》- SSL、TLS和密碼學學習筆記知道了協議的用處,這裏再貼一遍:javascript

爲何須要協議

加密基元自己沒有什麼用,例如加密和散列算法。咱們只有將這些元素組合成方案和協議才能知足複雜的安全需求。java

實例場景:
Alice和Bob要通訊。Mallory是個攻擊者。算法

咱們假設協議容許交換任意數量的消息。由於對稱加密擅長對大量數據進行加密,因此選取咱們最喜歡的AES算法來進行數據加密。使用AES,Alice和Bob能夠安全的交換消息,Malloc看不到他們通訊的內容。可是這還不夠,由於Malloc還能夠幹其它事情,例如神不知鬼不覺的修改消息。爲了解決這個問題,咱們使用只有Alice和Bob知道的散列密鑰計算每一個消息的MAC,在發送消息的同時,也發送消息的MAC。這時Mallory不再能修改消息了,然而他仍然能夠丟棄或者重發任意消息。爲了解決這個問題,咱們擴展協議,爲每條消息標記指定序號。最爲重要的是,咱們將序號做爲MAC計算數據的一部分。若是發現序號出現空缺,就能知道消息丟了。若是發現序號重複,就檢測重放攻擊。爲了獲得最佳效果,咱們使用某個特殊消息來標記會話結束。若是沒有這個消息,Mallory可以悄悄的結束(截斷)會話。若是全部措施以到位,Mallory最多隻能作到阻止Alice和Bob與其餘人通訊。咱們對此無能爲力。緩存

到目前爲止,有一大塊缺失:Alice和Bob如何協商獲得須要的兩個密鑰(一個用於加密(AES的密鑰),一個用於檢測完整性(MAC的密鑰)),同時還要小心Mallory?咱們經過爲協議添加兩個步驟來解決這個問題:
使用公鑰密碼對會話進行身份驗證。舉個例子,Alice生成一個隨機數,要求Bob對其簽名以證實真的是他,Bob也要求Alice作一樣的事情。
使用密鑰交換方案對加密密鑰進行祕密協商。舉個例子,Alice能夠生成全部密鑰,使用Bob的公鑰加密,再發送給Bob,這就是RSA密鑰交換的工做方式。安全

最後咱們協議完工時的狀態是:
以握手階段開始,包括身份驗證和密鑰交換
數據交換階段,保存機密性和完整性
以關閉序列結束。服務器

站在宏觀的角度看,咱們的協議與SSL和TLS完成的工做類似。網絡


這篇文章將描述TLS協議中的具體體現。session

TLS定義了四個核心子協議:

  • handshake protocol: 握手協議(包括身份驗證和密鑰交換)
  • change cipher spec protocol: 密鑰規格變動協議(會話恢復)
  • application data protocol: 應用數據協議(數據階段,保證機密性和完整性)
  • alert protocol: 警報協議(包括關閉序列的警告)

記錄協議

宏觀上TLS以記錄協議(record protocol)實現。併發

屏幕快照 2016-12-19 22.42.58.png

加密基元和加密套件

TLS協議須要哪些加密基元?
握手過程當中:app

  • 身份驗證:非對稱加密,公鑰加密,RSA
  • 密鑰交換:RSA,支持前向保密的DH,ECDH等

傳輸過程當中:

  • 加密算法:機密性的保證,例如AES,可有模式:CBC,ECB,GCM之類的,強度,128,256之類的。
  • 完整性的保證:例如MAC,PRF

以上基元和其它參數構成了密碼套件,它能夠精肯定義如何實現安全,密碼套件都傾向於使用較長的描述性名稱,而且至關一致:

TLS_密鑰交換_身份驗證_WITH_密碼_完整性保證複製代碼

其中密碼可寫爲:

算法_強度_模式複製代碼

所以密碼套件與下所示:

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256複製代碼

表示:
以RSA公鑰驗證身份,使用ECDHE密鑰交換,使用AES_128_GCM加密傳輸的數據,使用SHA256保證數據完整性。

握手協議的目的

在握手協議完成前,消息傳輸沒有收到任何保護(從技術上講,就是使用了TLS_NULL_WITH_NULL_NULL密碼套件),一旦握手完成,就開始按協商取得的鏈接參數進行加密和完整性驗證。
由上能夠握手協議的目的有:

  • 協商取得鏈接參數
  • 驗證身份
  • 交換密鑰
  • 驗證握手消息沒被第三方修改

密鑰交換

在TLS中,會話安全性取決於成爲主密鑰(master secret)的48字節共享密鑰。密鑰交換的目的是計算另外一個值,即預主密鑰(premaster secret),這個值是組成主密鑰的來源。
TLS支持許多密鑰交換算法,好比下表所示:

密鑰交換 描述
dh_anon Diffie-Hellman(DH)密鑰交換,未經身份驗證
dhe_rsa 臨時DH密鑰交換,使用RSA身份驗證
ecdh_anon 臨時橢圓曲線DH(elliptic curve DH,ECDH)密鑰交換,未經身份驗證
ecdhe_rsa 臨時ECDH密鑰交換,使用RSA身份驗證
ecdhe_ecdsa 臨時ECDH密鑰交換,使用RSA身份驗證

使用哪種密鑰交換是由協商的套件所決定。一旦套件決定下來,兩端都能瞭解按照哪一種算法繼續操做。

RSA密鑰交換
交換方式:客戶端生成預主密鑰,使用服務器公鑰對其加密,將其包含在ClientKeyExchange消息中,最後發送出去。服務器只須要使用私鑰解密這條消息就能獲得預主密鑰。
攻擊方式:對手能夠制定長期行動,攻擊者會記錄全部加密的流量,耐心等待有朝一日能夠獲得密鑰。好比,計算機能力的進步使暴力破解成爲可能,也能夠經過法律強制力、政治高壓、賄賂或強行進入使用該密鑰的服務器來取得密鑰。只要密鑰泄露,就能夠解密以前的全部流量了。(由於從私鑰能夠很容易推出預主密鑰,而後推出主密鑰。)

Diffie-Hellman密鑰交換
是一種密鑰協定的協議,支持前向保密,訣竅是正向計算簡單,逆向計算困難的數學函數,即便交換中的某些因子已被知曉,狀況也是同樣。最恰當的類比示例是混色:若是有兩種顏色,那麼狠容易將其混在一塊兒獲得第三種顏色,可是若是隻有第三種顏色,很難肯定到底是哪兩種顏色混合而成。
實現:DH密鑰交換須要6個參數:其中兩個(dh_p,dh_g)稱爲域參數,由服務器選定,協商過程當中,客戶端和服務器各自生成另外兩個參數,相互發送其中一個參數(dh_Ys和dh_Yc)到對端,在通過計算,最終獲得共享密鑰。

握手協議分爲3種:

  • 完整的握手,對服務器進行身份驗證(單向驗證)
  • 對客戶端和服務器都進行身份驗證(雙向驗證)
  • 恢復以前的會話採用的簡單握手

單向驗證
如下圖片來自:SSL/TLS 握手過程詳解
一、客戶端開始新的握手(ClientHello),

  • 將自身支持的功能提交給服務器(支持的密碼套件(Clipher Suites)列表,擴展(Extensions)裏面支持的散列算法,是否支持心跳(添加鏈接保活功能,使DTLS(依賴於UDP之上)也能長鏈接)等)。
  • 生成隨機數用來驗證服務器,這個隨機數在後面的摘要密鑰和加密密鑰的生成有關。
    Paste_Image.png

二、服務器選擇鏈接參數,並返回一個隨機數(ServerHello)

Paste_Image.png

三、服務器發送證書鏈(Certificate)

Paste_Image.png

四、根據鏈接參數中的密鑰交換方式,發送生產主密鑰的額外信息。(ServerKeyExchange)

Paste_Image.png

五、服務器通知本身完成了協商過程。(ServerHelloDone)

Paste_Image.png

六、客戶端發送生成主密鑰所需的額外信息(ClientKeyExchange:預主密鑰)。

//主密鑰生成函數PRF
master_seret = PRF(pre_master_secret,"master secret", ClientHello.random+ServerHello.random)複製代碼

7:客戶端切換加密方式並通知服務器(change clipeher spec:告訴服務器,我下面發的信息都要加密了)。
8:客戶端計算髮送和接收到的握手消息的MAC併發送(finished:客戶端發送第一條加密信息)。
9:服務器切換加密方式並通知客戶端(change clipher spec:告訴客戶端,我下面發的信息都要加密了)。
10:服務器計算髮送和接收到的握手信息的MAC併發送(finished:服務器發送第一條加密信息)。

由上面能夠看出,第一、2步Hello消息是用來協商取得鏈接,3-6步是用來驗證身份和交換密鑰,最後8和10步須要MAC是用來驗證握手消息沒被第三方修改。

以上握手流程圖示:

屏幕快照 2016-12-19 22.04.12.png

雙向驗證
只有已經通過身份驗證的服務器才容許請求客戶端身份驗證。
與單向驗證添加如下步驟:
一、服務器發送CertificateRequest消息請求客戶端進行身份驗證,消息中帶有接受的證書的公鑰和簽名算法或者證書頒發機構列表。
二、客戶端發送證書鏈給服務器Certificate。
三、客戶端使用CertificateVerify消息證實本身擁有的私鑰與以前發送的客戶端證書中的公鑰相對應。
圖示以下:

屏幕快照 2016-12-19 22.16.12.png

會話恢復
完整的握手協議很是複雜,須要不少握手消息和兩次網絡往返才能開始發送客戶端應用數據。此外握手執行的密鑰學操做一般須要密集的CPU處理。身份驗證一般以客戶端和服務器的證書驗證來完成,須要更多的工做。這其中許多消耗均可以經過簡短的握手方式節約下來。
最初的會話機制是再一次完整協商的鏈接斷開時,客戶端和服務器都會將會話的安全參數保存一段時間。
步驟:

  • 但願恢復先前會話的客戶端將合適的會話ID放入ClientHello消息,而後提交
  • 服務器若是願意恢復會話,就將相同的會話ID放入ServerHello消息返回
  • 服務器接着使用以前協商的主密鑰生成一套新的密鑰,再切換到加密模式,發送finished消息
  • 客戶端收到會話以恢復的消息後,也進行相同的操做。

這樣的結果是握手只須要一次網絡往還。
圖示:

屏幕快照 2016-12-19 22.29.08.png

用來替代服務器會話緩存與恢復的方案:
會話票證(session ticker):除了全部的狀態都保存在客戶端(與HTTPCookie原理相似)以外,其消息流與服務器會話緩存一致

應用數據協議

記錄層使用當前鏈接安全參數對這些信息進行打包、碎片整理和加密。

警報協議

以簡單的方式告知對端通訊出現異常,一般會攜帶close_notify異常,在鏈接關閉時使用。

關閉鏈接

關閉鏈接警報用以有序的方式關閉TLS鏈接。
步驟:

  • 一旦一端決定關閉鏈接,就會發送一個close_notify警報。
  • 另外一端在接收到這個警告事後,會丟棄任何還未寫出的數據,併發送本身的close_notify警告
  • 在警告以後到來的任何消息都將被忽略。

能夠避免截斷攻擊,由於沒有關閉協議,通訊雙方沒法確認是遭受攻擊仍是通訊結束。

個人簡書主頁:www.jianshu.com/users/b92ab…

相關文章
相關標籤/搜索