本文同時發表在https://github.com/zhangyachen/zhangyachen.github.io/issues/31
復習基本概念
- 對稱密碼:加密和解密使用同一密匙。
- 公鑰密碼:加密和解密使用不同密鑰的方式。
- 單向散列函數:計算散列值,保證的不是機密性,而是完整性。
- 消息認證碼:確認消息是否被篡改,而且能夠確認消息是否來自所期待的通信對象。
- 數字簽名:由於消息認證碼使用公鑰進行加密的,會出現發送方否認的情況,所以為了防止這種情況出現,發送方使用私鑰進行加密散列值。
- 證書:我們必須保證驗證數字簽名的公鑰必須屬於發送方,否則數字簽名會失效。為了確認自己得到的公鑰是否合法,我們需要使用證書。
什么是SSL/TLS
來看一下通過http發送請求的場景:
但是此種情況下,信用卡號就很有可能被竊聽。於是,我們可以使用SSL或者TLS作為對通信進行加密的協議,然后在此之上承載http。通過對此兩種協議的疊加,我們就對HTTP的通信進行加密,防止竊聽。
以上面的例子為例,如果我們想要達到安全的通信,必須達到以下幾點:
- 信用卡號不被竊聽
- 信用卡號不被篡改
- 確認通信對方是真實的而不是假冒的
以上問題抽象出來就是:
- 機密性
- 完整性
- 認證問題
通過文章最開始提到的密碼技術,我們可以想到機密性可以用對稱密碼解決(這里的竊聽不是指發送內容不能被攻擊者得到,而是攻擊者即使得到發送內容也不能理解或者破譯)。由於對稱密碼不能被攻擊者預測,因此我們使用偽隨機數生成器來生成密鑰。若要將對稱密碼的密鑰發送給通信方而不被攻擊者竊聽,可以使用公鑰密碼或者Diffie-Hellman密鑰交換。
識別篡改可以使用消息認證碼技術.
對通信對象的認證,可以使用對公鑰加上數字簽名所生成的證書。
我們需要一個“框架”將上述工具組合起來,SSL/TLS協議就扮演了這樣一個框架的角色。
上面的例子是SSL/TLS承載HTTP協議,其實SSL/TLS還可以承載很多協議,例如:SMTP、POP3。
SSL與TLS的區別
SSL是1994年網景公司設計的一種協議,並在該公司的Web瀏覽器中進行了實現。隨后很多Web瀏覽器都采用了這一種協議,使其成為了事實上的行業標准。SSL已經於1995年發布了3.0版本。
TLS是IETF在SSL3.0的基礎上設計的協議。在1999年作為RFC2246發布的TLS1.0,實際上相當於SSL3.1。
為什么使用SSL/TLS
- 所有信息都是加密傳播,第三方無法竊聽。
- 具有校驗機制,一旦被篡改,通信雙方會立刻發現。
- 配備身份證書,防止身份被冒充。
SSL/TLS的層次化協議
TLS協議分為TLS記錄協議和TLS握手協議。位於底層的TLS記錄協議負責進行加密,位於上層的TLS握手協議負責加密以外的其他操作。而上層的TLS握手協議又分為4個子協議。
記錄協議
負責消息的壓縮、加密以及數據的認證。
處理過程如下:
- 將消息分割成小片段,然后對每個片段進行壓縮,壓縮算法需要與通信對象進行協商。
- 將每個壓縮的片段加上消息認證碼,這是為了保證完整性並進行數據的認證。通過附加消息的MAC值,可以識別出篡改。與此同時,為了防止重放攻擊,在計算消息認證碼時,還加上了片段的編號,單向散列函數的算法。以及消息認證碼所使用的共享密鑰都需要與通信對象協商決定。
- 經過壓縮的片段加上消息認證碼會一起通過對稱密碼進行加密。加密使用CBC模式,CBC的初始化向量(IV)通過主密碼(master secret)生成,而對稱密碼的算法以及共享密鑰需要協商。
- 上述的加密數據再加上數據類型、版本號、壓縮后的長度組成的報頭就是最終的報文數據。
握手協議
負責生產共享密鑰以及交換證書。
握手協議主要分為4個子協議:握手協議、密碼規格變更協議、警告協議和應用數據協議。
握手協議
負責在客戶端和服務器之間協商決定密碼算法和共享密鑰。基於證書的認證也在這一步完成。這段協議相當於下面的會話:
客戶端:“你好,我能理解的密碼套件有RSA/3DES,或者DSS/AES,請問我們使用哪一種?”
服務器:“你好,我們使用RSA/3DES吧,這是我的證書。”
協商之后,就會互相發出信號來切換密碼。負責發出信號的就是下面介紹的密碼規格變更協議。
密碼規格變更協議
負責向通信對象傳達變更密碼方式的信號。
客戶端:“我們按照剛才的約定切換密碼吧。1,2,3”
中途發生錯誤時,就會通過下面的警告協議傳達給對方。
警告協議
負責向通信對象傳達變更密碼方式的信號。
客戶端:“我們按照剛才的約定切換密碼吧。1,2,3”
中途發生錯誤時,就會通過下面的警告協議傳達給對方。
警告協議
服務器:“剛才的消息無法正確解析哦。”
應用數據協議
將TLS上面承載的應用數據傳達給通信對象的協議。
使用SSL/TLS進行通信
(圖片太長了,截了兩次,o(╯□╰)o)
一些重要握手過程:
ClientHello
客戶端向服務器發出加密通信的請求。
在這一步,客戶端主要向服務器提供以下信息。
- 支持的協議版本,比如TLS 1.0版。
- 當前時間
- 一個客戶端生成的隨機數,稍后用於生成"對話密鑰"。
- 會話ID
- 支持的加密方法,比如RSA公鑰加密。
- 支持的壓縮方法。
“會話ID”是當客戶端和服務器希望重新使用之前建立的會話(通信路徑)時所使用的信息。
ServerHello
服務器收到客戶端請求后,向客戶端發出回應。服務器的回應包含以下內容。
- 確認使用的加密通信協議版本,比如TLS 1.0版本。如果瀏覽器與服務器支持的版本不一致,服務器關閉加密通信。
- 一個服務器生成的隨機數,稍后用於生成"對話密鑰"。
- 當前時間
- 會話ID
- 確認使用的加密方法,比如RSA公鑰加密。
- 密碼套件。
Certificate
服務器發送Certificate消息。包含以下內容
- 證書清單
首先發送的是服務器的證書,然后會按順序發送對服務器證書簽名的認證機構的證書。
當以匿名方式通信時,不發送Certificate消息。
ServerKeyExchange
當Certificate消息不足以滿足需求時(例如匿名方式通信),服務器會通過ServerKeyExchange消息向客戶端發送一些必要信息。
當使用RSA時,服務器發送N與E,也就是公鑰。
當使用DH算法時,服務器發送P、G、G的x次方modP(DH算法的公開參數)
ClientKeyExchange
客戶端從服務器的證書中取出服務器的公鑰,然后向服務器發送以下信息。
- 一個隨機數。該隨機數用服務器公鑰加密,防止被竊聽。該隨機數也叫作pre-master key。有了它以后,客戶端和服務器就同時有了三個隨機數,接着雙方就用事先商定的加密方法,各自生成本次會話所用的同一把主密碼。而主密碼用來加密客戶端和服務器的通信內容。
當使用RSA時,會隨ClientKeyExchange一起發送經過加密的預備主密碼。
當使用DH算法時,會隨ClientKeyExchange一起發送DH的公開值,即Y(G的x次方模P),之后雙方也能算出相同的pre-master key。
主密碼
非常重要的一個數值,TLS密碼通信的機密性和數據的認證全部依靠這個數值。
主密碼的計算
主密碼依賴如下信息計算出來:
- 預備主密碼
- 客戶端隨機數
- 服務器隨機數
當使用RSA公鑰密碼時,客戶端在發送ClientKeyExchange消息時,將經過加密的預備主密碼一起發送給服務器。
當使用DH密鑰交換時,客戶端在發送ClientKeyExchange消息時,將DH的公開值一起發送給服務器。根據這個值,客戶端和服務器會各自生成預備主密碼。
當根據預備主密碼計算主密碼時,會使用兩個單向散列函數(MD5和SHA-1)組合而成的偽隨機數生成器。之所以用兩個單向散列函數,是為了提高安全性。
為什么一定要三個隨機數
引用dog250的理解
不管是客戶端還是服務器,都需要隨機數,這樣生成的密鑰才不會每次都一樣。由於SSL協議中證書是靜態的,因此十分有必要引入一種隨機因素來保證協商出來的密鑰的隨機性。
對於RSA密鑰交換算法來說,pre-master-key本身就是一個隨機數,再加上hello消息中的隨機,三個隨機數通過一個密鑰導出器最終導出一個對稱密鑰。
pre master的存在在於SSL協議不信任每個主機都能產生完全隨機的隨機數,如果隨機數不隨機,那么pre master secret就有可能被猜出來,那么僅適用pre master secret作為密鑰就不合適了,因此必須引入新的隨機因素,那么客戶端和服務器加上pre master secret三個隨機數一同生成的密鑰就不容易被猜出了,一個偽隨機可能完全不隨機,可是是三個偽隨機就十分接近隨機了,每增加一個自由度,隨機性增加的可不是一。
主密碼的目的
主密碼用於生成下列6種信息:
- 對稱密碼的密鑰(客戶端->服務器)
- 對稱密碼的密鑰(客戶端<-服務器)
- 消息認證碼的密鑰(客戶端->服務器)
- 消息認證碼的密鑰(客戶端<-服務器)
- 對稱密碼的CBC模式所使用的初始化向量(客戶端->服務器)
- 對稱密碼的CBC模式所使用的初始化向量(客戶端<-服務器)
SSL/TLS密碼技術小結
對SSL/TLS的攻擊
- 對各個密碼技術的攻擊,比如對稱密碼。但是,SSL/TLS並不依賴於某種密碼組件,當發現某種對稱密碼存在弱點時,換一種對稱密碼即可。
- 對偽隨機數進行攻擊。
- 利用證書的時間差進行攻擊。
要驗證證書必須使用CRL(證書作廢清單)。如果客戶端沒有安裝最新版的CRL,那么SSL/TLS也無法保證通信的安全。
TLS握手優化
這部分還沒涉獵過,先找個文章mark下。
https://imququ.com/post/optimize-tls-handshake.html
參考資料:《圖解密碼技術》
http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html