1. 程式人生 > >SSL/TLS原理詳解

SSL/TLS原理詳解

targe ssl 證明 自帶 安全套 能夠 qiniu 解析 number

SSL/TLS作為一種互聯網安全加密技術,原理較為復雜,枯燥而無味,我也是試圖理解之後重新整理,盡量做到層次清晰。正文開始。

1. SSL/TLS概覽

1.1 整體結構

SSL是一個介於HTTP協議與TCP之間的一個可選層,其位置大致如下:
技術分享圖片

  • SSL:(Secure Socket Layer,安全套接字層),為Netscape所研發,用以保障在Internet上數據傳輸之安全,利用數據加密(Encryption)技術,可確保數據在網絡上之傳輸過程中不會被截取。當前版本為3.0。它已被廣泛地用於Web瀏覽器與服務器之間的身份認證和加密數據傳輸。
    SSL協議位於TCP/IP協議與各種應用層協議之間,為數據通訊提供安全支持。SSL協議可分為兩層: SSL記錄協議(SSL Record Protocol):它建立在可靠的傳輸協議(如TCP)之上,為高層協議提供數據封裝、壓縮、加密等基本功能的支持。 SSL握手協議(SSL Handshake Protocol):它建立在SSL記錄協議之上,用於在實際的數據傳輸開始前,通訊雙方進行身份認證、協商加密算法、交換加密密鑰等。

  • 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 Record)和 TLS 握手協議(TLS Handshake)。較低的層為 TLS 記錄協議,位於某個可靠的傳輸協議(例如 TCP)上面。

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

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

1.2 TLS與SSL的差異

  1. 版本號:TLS記錄格式與SSL記錄格式相同,但版本號的值不同,TLS的版本1.0使用的版本號為SSLv3.1。
  2. 報文鑒別碼:SSLv3.0和TLS的MAC算法及MAC計算的範圍不同。TLS使用了RFC-2104定義的HMAC算法。SSLv3.0使用了相似的算法,兩者差別在於SSLv3.0中,填充字節與密鑰之間采用的是連接運算,而HMAC算法采用的是異或運算。但是兩者的安全程度是相同的。
  3. 偽隨機函數:TLS使用了稱為PRF的偽隨機函數來將密鑰擴展成數據塊,是更安全的方式。
  4. 報警代碼:TLS支持幾乎所有的SSLv3.0報警代碼,而且TLS還補充定義了很多報警代碼,如解密失敗(decryption_failed)、記錄溢出(record_overflow)、未知CA(unknown_ca)、拒絕訪問(access_denied)等。
  5. 密文族和客戶證書:SSLv3.0和TLS存在少量差別,即TLS不支持Fortezza密鑰交換、加密算法和客戶證書。
  6. certificate_verify和finished消息:SSLv3.0和TLS在用certificate_verify和finished消息計算MD5和SHA-1散列碼時,計算的輸入有少許差別,但安全性相當。
  7. 加密計算:TLS與SSLv3.0在計算主密值(master secret)時采用的方式不同。
  8. 填充:用戶數據加密之前需要增加的填充字節。在SSL中,填充後的數據長度要達到密文塊長度的最小整數倍。而在TLS中,填充後的數據長度可以是密文塊長度的任意整數倍(但填充的最大長度為255字節),這種方式可以防止基於對報文長度進行分析的攻擊。

TLS的主要增強內容

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

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

TLS對於安全性的改進

  1. 對於消息認證使用密鑰散列法:TLS 使用“消息認證代碼的密鑰散列法”(HMAC),當記錄在開放的網絡(如因特網)上傳送時,該代碼確保記錄不會被變更。SSLv3.0還提供鍵控消息認證,但HMAC比SSLv3.0使用的(消息認證代碼)MAC 功能更安全。
  2. 增強的偽隨機功能(PRF):PRF生成密鑰數據。在TLS中,HMAC定義PRF。PRF使用兩種散列算法保證其安全性。如果任一算法暴露了,只要第二種算法未暴露,則數據仍然是安全的。
  3. 改進的已完成消息驗證:TLS和SSLv3.0都對兩個端點提供已完成的消息,該消息認證交換的消息沒有被變更。然而,TLS將此已完成消息基於PRF和HMAC值之上,這也比SSLv3.0更安全。
  4. 一致證書處理:與SSLv3.0不同,TLS試圖指定必須在TLS之間實現交換的證書類型。
  5. 特定警報消息:TLS提供更多的特定和附加警報,以指示任一會話端點檢測到的問題。TLS還對何時應該發送某些警報進行記錄。

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

SSL協議分為兩部分:Handshake Protocol和Record Protocol。其中Handshake Protocol用來協商密鑰,協議的大部分內容就是通信雙方如何利用它來安全的協商出一份密鑰。 Record Protocol則定義了傳輸的格式。

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

SSL缺省只進行server端的認證,客戶端的認證是可選的。以下是其流程圖(摘自TLS協議)。
技術分享圖片

2.1 客戶端發出請求(ClientHello)

由於客戶端(如瀏覽器)對一些加解密算法的支持程度不一樣,但是在TLS協議傳輸過程中必須使用同一套加解密算法才能保證數據能夠正常的加解密。在TLS握手階段,客戶端首先要告知服務端,自己支持哪些加密算法,所以客戶端需要將本地支持的加密套件(Cipher Suite)的列表傳送給服務端。除此之外,客戶端還要產生一個隨機數,這個隨機數一方面需要在客戶端保存,另一方面需要傳送給服務端,客戶端的隨機數需要跟服務端產生的隨機數結合起來產生後面要講到的 Master Secret 。

綜上,在這一步,客戶端主要向服務器提供以下信息:

  1. 支持的協議版本,比如TLS 1.0版
  2. 一個客戶端生成的隨機數,稍後用於生成"對話密鑰"
  3. 支持的加密方法,比如RSA公鑰加密
  4. 支持的壓縮方法

2.2 服務器回應(SeverHello)

上圖中,從Server Hello到Server Done,有些服務端的實現是每條單獨發送,有服務端實現是合並到一起發送。Sever Hello和Server Done都是只有頭沒有內容的數據。

服務端在接收到客戶端的Client Hello之後,服務端需要將自己的證書發送給客戶端。這個證書是對於服務端的一種認證。例如,客戶端收到了一個來自於稱自己是www.alipay.com的數據,但是如何證明對方是合法的alipay支付寶呢?這就是證書的作用,支付寶的證書可以證明它是alipay,而不是財付通。證書是需要申請,並由專門的數字證書認證機構(CA)通過非常嚴格的審核之後頒發的電子證書。頒發證書的同時會產生一個私鑰和公鑰。私鑰由服務端自己保存,不可泄漏。公鑰則是附帶在證書的信息中,可以公開的。證書本身也附帶一個證書電子簽名,這個簽名用來驗證證書的完整性和真實性,可以防止證書被串改。另外,證書還有個有效期。

在服務端向客戶端發送的證書中沒有提供足夠的信息(證書公鑰)的時候,還可以向客戶端發送一個 Server Key Exchange,

此外,對於非常重要的保密數據,服務端還需要對客戶端進行驗證,以保證數據傳送給了安全的合法的客戶端。服務端可以向客戶端發出 Cerficate Request 消息,要求客戶端發送證書對客戶端的合法性進行驗證。比如,金融機構往往只允許認證客戶連入自己的網絡,就會向正式客戶提供USB密鑰,裏面就包含了一張客戶端證書。

跟客戶端一樣,服務端也需要產生一個隨機數發送給客戶端。客戶端和服務端都需要使用這兩個隨機數來產生Master Secret。

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

綜上,在這一步,服務器的回應包含以下內容:

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

2.3 客戶端回應(Certificate Verify)

Client Key Exchange

如果服務端需要對客戶端進行驗證,在客戶端收到服務端的 Server Hello 消息之後,首先需要向服務端發送客戶端的證書,讓服務端來驗證客戶端的合法性。

Certificate Verify
接著,客戶端需要對服務端的證書進行檢查,如果證書不是可信機構頒布、或者證書中的域名與實際域名不一致、或者證書已經過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通信。如果證書沒有問題,客戶端就會從服務器證書中取出服務器的公鑰。然後,向服務器發送下面三項信息:

  1. 一個隨機數。該隨機數用服務器公鑰加密,防止被竊聽
  2. 編碼改變通知,表示隨後的信息都將用雙方商定的加密方法和密鑰發送
  3. 客戶端握手結束通知,表示客戶端的握手階段已經結束。這一項同時也是前面發送的所有內容的hash值,用來供服務器校驗

上面第一項的隨機數,是整個握手階段出現的第三個隨機數,它是客戶端使用一些加密算法(例如:RSA, Diffie-Hellman)產生一個48個字節的Key,這個Key叫 PreMaster Secret,很多材料上也被稱作 PreMaster Key。

ChangeCipherSpec
ChangeCipherSpec是一個獨立的協議,體現在數據包中就是一個字節的數據,用於告知服務端,客戶端已經切換到之前協商好的加密套件(Cipher Suite)的狀態,準備使用之前協商好的加密套件加密數據並傳輸了。

在ChangecipherSpec傳輸完畢之後,客戶端會使用之前協商好的加密套件和Session Secret加密一段 Finish 的數據傳送給服務端,此數據是為了在正式傳輸應用數據之前對剛剛握手建立起來的加解密通道進行驗證。

2.4 服務器的最後回應(Server Finish)

服務端在接收到客戶端傳過來的 PreMaster 加密數據之後,使用私鑰對這段加密數據進行解密,並對數據進行驗證,也會使用跟客戶端同樣的方式生成 Session Secret,一切準備好之後,會給客戶端發送一個 ChangeCipherSpec,告知客戶端已經切換到協商過的加密套件狀態,準備使用加密套件和 Session Secret加密數據了。之後,服務端也會使用 Session Secret 加密一段 Finish 消息發送給客戶端,以驗證之前通過握手建立起來的加解密通道是否成功。

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

2.5 幾個secret

Secret Keys
上面的分析和講解主要是為了突出握手的過程,所以PreMaster secret,Master secret,session secret都是一代而過,但是對於Https,SSL/TLS深入的理解和掌握,這些Secret Keys是非常重要的部分。所以,準備把這些Secret Keys抽出來單獨分析和講解。

我們先來看看這些Secret Keys的生成過程以及作用流程圖:
技術分享圖片

PreMaster secret
PreMaster Secret是在客戶端使用RSA或者Diffie-Hellman等加密算法生成的。它將用來跟服務端和客戶端在Hello階段產生的隨機數結合在一起生成 Master Secret。在客戶端使用服務端的公鑰對PreMaster Secret進行加密之後傳送給服務端,服務端將使用私鑰進行解密得到PreMaster secret。也就是說服務端和客戶端都有一份相同的PreMaster secret和隨機數。

PreMaster secret前兩個字節是TLS的版本號,這是一個比較重要的用來核對握手數據的版本號,因為在Client Hello階段,客戶端會發送一份加密套件列表和當前支持的SSL/TLS的版本號給服務端,而且是使用明文傳送的,如果握手的數據包被破解之後,攻擊者很有可能串改數據包,選擇一個安全性較低的加密套件和版本給服務端,從而對數據進行破解。所以,服務端需要對密文中解密出來對的PreMaster版本號跟之前Client Hello階段的版本號進行對比,如果版本號變低,則說明被串改,則立即停止發送任何消息。

關於PreMaster Secret(Key)的計算請參考 Https SSL/TLS PreMaster/Master Secret(Key)計算。

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。Client write MAC key是客戶端發數據的session secret,Server write MAC secret是服務端發送數據的session key。MAC(Message Authentication Code),是一個數字簽名,用來驗證數據的完整性,可以檢測到數據是否被串改。

關於Session Secret(Key)的計算請參考 Https SSL/TLS Session Secret(Key)計算。

2.6 應用數據傳輸

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

2.7 總結

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

3. 附:密鑰協商的形象化比喻

如果上面的說明不夠清晰,這裏我們用個形象的比喻,我們假設A與B通信,A是SSL客戶端,B是SSL服務器端,加密後的消息放在方括號[]裏,以突出明文消息的區別。雙方的處理動作的說明用圓括號()括起。

A:我想和你安全的通話,我這裏的對稱加密算法有DES,RC5,密鑰交換算法有RSA和DH,摘要算法有MD5和SHA。

B:我們用DES-RSA-SHA這對組合好了。
這是我的證書,裏面有我的名字和公鑰,你拿去驗證一下我的身份(把證書發給A)。
目前沒有別的可說的了。

A:(查看證書上B的名字是否無誤,並通過手頭早已有的CA的證書驗證了B的證書的真實性,如果其中一項有誤,發出警告並斷開連接,這一步保證了B的公鑰的真實性)
(產生一份秘密消息,這份秘密消息處理後將用作加密密鑰,加密初始化向量(IV)和hmac的密鑰。將這份秘密消息-協議中稱為per_master_secret-用B的公鑰加密,封裝成稱作ClientKeyExchange的消息。由於用了B的公鑰,保證了第三方無法竊聽)
我生成了一份秘密消息,並用你的公鑰加密了,給你(把ClientKeyExchange發給B)
註意,下面我就要用加密的辦法給你發消息了!
(將秘密消息進行處理,生成加密密鑰,加密初始化向量和hmac的密鑰)
[我說完了]

B:(用自己的私鑰將ClientKeyExchange中的秘密消息解密出來,然後將秘密消息進行處理,生成加密密鑰,加密初始化向量和hmac的密鑰,這時雙方已經安全的協商出一套加密辦法了)
註意,我也要開始用加密的辦法給你發消息了!
[我說完了]

A: [我的秘密是...]

B: [其它人不會聽到的...]

4. SSL安全性

SecurityPortal在2000年底有一份文章《The End of SSL and SSH?》激起了很多的討論, 目前也有一些成熟的工具如dsniff(http://www.monkey.org/~dugsong/dsniff/)可以通過man in the middle攻擊來截獲https的消息。

從上面的原理可知,SSL的結構是嚴謹的,問題一般出現在實際不嚴謹的應用中。常見的攻擊就是middle in the middle攻擊,它是指在A和B通信的同時,有第三方C處於信道的中間,可以完全聽到A與B通信的消息,並可攔截,替換和添加這些消息。

  1. SSL可以允許多種密鑰交換算法,而有些算法,如DH,沒有證書的概念,這樣A便無法驗證B的公鑰和身份的真實性,從而C可以輕易的冒充,用自己的密鑰與雙方通信,從而竊聽到別人談話的內容。
    而為了防止middle in the middle攻擊,應該采用有證書的密鑰交換算法。
  2. 有了證書以後,如果C用自己的證書替換掉原有的證書之後,A的瀏覽器會彈出一個警告框進行警告,但又有多少人會註意這個警告呢?
  3. 由於美國密碼出口的限制,IE,netscape等瀏覽器所支持的加密強度是很弱的,如果只采用瀏覽器自帶的加密功能的話,理論上存在被破解可能。

5. 代理

下面探討一下SSL的代理是怎樣工作的
當在瀏覽器裏設置了https的代理,而且裏輸入了https://www.example.com之後,瀏覽器會與proxy建立tcp鏈接,然後向其發出這麽一段消息:

   CONNECT server.example.com:443 HTTP/1.1
   Host: server.example.com:443

然後proxy會向webserver端建立tcp連接,之後,這個代理便完全成了個內容轉發裝置。瀏覽器與web server會建立一個安全通道,因此這個安全通道是端到端的,盡管所有的信息流過了proxy,但其內容proxy是無法解密和改動的(當然要由證書的支持,否則這個地方便是個man in the middle攻擊的好場所,見上面的安全部分)。

SSL/TLS原理詳解