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

lyxia_iOS發表於2016-12-19

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

為什麼需要協議

加密基元本身沒有什麼用,例如加密和雜湊演算法。我們只有將這些元素組合成方案和協議才能滿足複雜的安全需求。

例項場景:
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協議中的具體體現。

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

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

記錄協議

巨集觀上TLS以記錄協議(record protocol)實現。

《HTTPS權威指南》-協議學習筆記
螢幕快照 2016-12-19 22.42.58.png

加密基元和加密套件

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

  • 身份驗證:非對稱加密,公鑰加密,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 握手過程詳解
1、客戶端開始新的握手(ClientHello),

  • 將自身支援的功能提交給伺服器(支援的密碼套件(Clipher Suites)列表,擴充套件(Extensions)裡面支援的雜湊演算法,是否支援心跳(新增連線保活功能,使DTLS(依賴於UDP之上)也能長連線)等)。
  • 生成隨機數用來驗證伺服器,這個隨機數在後面的摘要金鑰和加密金鑰的生成有關。
    《HTTPS權威指南》-協議學習筆記
    Paste_Image.png

2、伺服器選擇連線引數,並返回一個隨機數(ServerHello)

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

3、伺服器傳送證照鏈(Certificate)

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

4、根據連線引數中的金鑰交換方式,傳送生產主金鑰的額外資訊。(ServerKeyExchange)

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

5、伺服器通知自己完成了協商過程。(ServerHelloDone)

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

6、客戶端傳送生成主金鑰所需的額外資訊(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:伺服器傳送第一條加密資訊)。

由上面可以看出,第1、2步Hello訊息是用來協商取得連線,3-6步是用來驗證身份和交換金鑰,最後8和10步需要MAC是用來驗證握手訊息沒被第三方修改。

以上握手流程圖示:

《HTTPS權威指南》-協議學習筆記
螢幕快照 2016-12-19 22.04.12.png

雙向驗證
只有已經經過身份驗證的伺服器才允許請求客戶端身份驗證。
與單向驗證新增以下步驟:
1、伺服器傳送CertificateRequest訊息請求客戶端進行身份驗證,訊息中帶有接受的證照的公鑰和簽名演算法或者證照頒發機構列表。
2、客戶端傳送證照鏈給伺服器Certificate。
3、客戶端使用CertificateVerify訊息證明自己擁有的私鑰與之前傳送的客戶端證照中的公鑰相對應。
圖示如下:

《HTTPS權威指南》-協議學習筆記
螢幕快照 2016-12-19 22.16.12.png

會話恢復
完整的握手協議非常複雜,需要很多握手訊息和兩次網路往返才能開始傳送客戶端應用資料。此外握手執行的金鑰學操作通常需要密集的CPU處理。身份驗證通常以客戶端和伺服器的證照驗證來完成,需要更多的工作。這其中許多消耗都可以通過簡短的握手方式節約下來。
最初的會話機制是再一次完整協商的連線斷開時,客戶端和伺服器都會將會話的安全引數儲存一段時間。
步驟:

  • 希望恢復先前會話的客戶端將合適的會話ID放入ClientHello訊息,然後提交
  • 伺服器如果願意恢復會話,就將相同的會話ID放入ServerHello訊息返回
  • 伺服器接著使用之前協商的主金鑰生成一套新的金鑰,再切換到加密模式,傳送finished訊息
  • 客戶端收到會話以恢復的訊息後,也進行相同的操作。

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

《HTTPS權威指南》-協議學習筆記
螢幕快照 2016-12-19 22.29.08.png

用來替代伺服器會話快取與恢復的方案:
會話票證(session ticker):除了所有的狀態都儲存在客戶端(與HTTPCookie原理類似)之外,其訊息流與伺服器會話快取一致

應用資料協議

記錄層使用當前連線安全引數對這些資訊進行打包、碎片整理和加密。

警報協議

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

關閉連線

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

  • 一旦一端決定關閉連線,就會傳送一個close_notify警報。
  • 另一端在接收到這個警告過後,會丟棄任何還未寫出的資料,併傳送自己的close_notify警告
  • 在警告之後到來的任何訊息都將被忽略。

可以避免截斷攻擊,因為沒有關閉協議,通訊雙方無法確認是遭受攻擊還是通訊結束。

我的簡書主頁:www.jianshu.com/users/b92ab…

相關文章