一、概述
SSL協議是最早Netscape公司開發的安全通信協議,用於瀏覽器安全通信。到SSL Version3,提交作爲IFTF草案,已經廣泛的應用Intetnet通信。之後IETF對SSLv3稍作改動並更名爲TLS1.0,對應 RFC2246,之後的TLS1.1、TLS1.2先後被接受爲RFC4346,RFC5246,另外由於TLS是基於TCP協議設計,導致其不能處理獨 立紀錄,不允許SSL時有數據丟失,在RFC4347中提出了一種“Datagram TLS”---DTLS,可以理解爲TLS1.1的分支。
SSL/TLS協議的設計目標是保證數據的機密性和完整性。因此在SSL/TLS協議中包含了3類算法:對稱加密算法(保證機密性),數據簽名算法(保證完整性)和公鑰算法(用於交換密鑰)。下面以TLS1.0爲基準介紹SSL/TLS協議簇加解密流程。
二、加解密流程
SSL/TLS協議的基本數據交互流程如下圖:
加解密流程詳細介紹如下:
Client Hello :表示客戶端向服務器發起SSL握手請求。
客戶端:生成一個32byte的random用於計算主密鑰、加密密鑰和消息的數字簽名。在cipher suites中指明自己支持的對稱加密、非對稱加密和數字簽名算法。
Server Hello:表示服務器相應客戶端的SSL握手請求。
服務器端:生成一個32byte的random用於計算主密鑰、加密密鑰和消息的數字簽名。生成一個23byte的SessionID。在client cipher suites中挑選一個加密強度最高的算法組合,作爲雙方的通訊的算法。
如TLS_RSA_WITH_AES_128_CBC_SHA表示通訊協議時TLS、非對稱加密算法爲RSA、對稱加密算法爲AES_128_CBC、數字簽名算法爲SHA。
Certificate:服務端證書。
服務器端:如果服務端證書是Base64編碼,首先把證書進行Base64解碼,得到的是使用ASN.1格式編碼的X.509證書。
客戶端:根據收到的證書,判斷其合法性,並計算得到服務器的公鑰(對於RSA算法,是解析得到n和e,對於DH算法解析得到a和q)。
證書合法性的判斷方法:
~頒佈者的合法性(hash值)
~有效期
~簽名值是否合法:首先對證書中除簽名值部分的內容按照證書中的簽名
算法進行簽名,把得到的簽名按照asn.1編碼方式進行編碼:OBJECT格式的簽名算法+ ASN_OCTET_STRING格式的簽名值A;把證書中的簽名值按照證書中的主體公鑰算法進行解密得到B;當A和B完全相同時認爲證書有效(證書製作 過程中的簽名值計算方法:計算得到A,和客戶端計算方法相同,用服務器私鑰對A進行加密,得到證書中的簽名值)
一般情況下客戶端收到的是一個證書鏈,第一個是服務器的證書,之後是服務器證書籤發者。。。最後是自簽名的根證書。如下圖。在實際解析中先要驗證根CA的證書,然後是直接證書籤發者證書,最後是服務器終端證書。
Certificate Request:當服務器需要驗證客戶端證書時使用。
Server Key Exchange:用於交換對車密鑰,只有在使用RSA擴展選項或者DH算法時纔會使用。
Server Hello Done:表示握手消息結束。
Client Key Exchange:交換預主密鑰。
客戶端:
RSA算法:
隨機生成48byte的預主密鑰,把48byte的第一個字節設置成主版本號,第二個字節設置成次版本號。用步驟2中協商得到的非對稱加密算法進行加密。傳遞給服務器端。
DH算法:
得到隨機數Xc,計算得到Yc,把Yc通過Client Key Exchange消息明文傳遞爲服務器端;根據a,q,Xc,Ys計算得到預主密鑰。
客戶端和服務器端都需要根據預主密鑰計算得到主密鑰、加密密鑰和簽名密鑰,方法如下:
RSA算法:
接到客戶端加密的預主密鑰,按照非對稱密鑰進行解密,得到預主密鑰。然後按照PRF算法計算得到主密鑰。(生成主密鑰的算法SSL和TLS略有不同。)
DH算法:
根據a,q,Xs,Yc計算得到預主密鑰。
根據預主密鑰計算得到主密鑰的算法(PRF算法):就是帶密鑰的MD5簽名算法和帶密鑰SHA簽名算法得到的結果異或得到的。
MD5:
密鑰:預主密鑰的前24byte,簽名文本:字符串“master secret”+服務器端32byte的random + 客戶端32byte的random,生成48byte的MD5Hash值
SHA:
密鑰:預主密鑰的後24byte,簽名文本:字符串“master secret”+服務器端32byte的random + 客戶端32byte的random,生成48byte的SHAHash值
得到主密鑰:MD5Hash XOR SHAHash
最後根據主密鑰計算的到6個實際使用的密 鑰:client_write_MAC_secret;server_write_MAC_secret;client_write_key;server_write_key;client_write_IV;server_write_IV;
計算方法和計算主密鑰的方法類似,都使用PRF算法。不同的是提供給MD5和SHA的密鑰是主密鑰,最後生成的Hash長度爲148。然後把148byte的Hash依次賦值給上述6個實際密鑰。
Change Cipher Spec:表示之後的消息傳輸都將採用對稱加密方式進行。
Encryted HandShake Message:加密的Finish報文,用於驗證雙方協商的對稱加密算法、客戶端密鑰。
~客戶端給服務器發送的Finished報文:
客戶端:對字符串“client finished”應用PRF算法:MD5和SHA的密鑰是主密鑰,加密的密文是SSL握手以來所有消息的串聯,生成的Hash值爲12Byte;對生成 的12byte應用HMAC算法,算法的密鑰是client_write_MAC_secret,把計算得到的MAC值添加到Hash後面;如果是對稱加 密算法是塊加密算法,那麼還需要填充pad。最後用第2步中協商的對稱加密算法對上述數據進行整體加密,加密密鑰是前面中計算得到的 client_write_key。
服務器端:首先用密鑰爲的client_write_key對稱加密算法對數據進行解密,計算字符串“client finished”的MAC值和客戶端發送過來的12byte進行比較,相同則認爲client_write_key的對稱加密正確,再用 client_write_MAC_secret計算MAC值,和客戶端的數據進行比較,如果相同則認爲client_write_MAC_secret 正確。
~服務器給客戶端發送的Finished報文:
和客戶端給服務器發送的Finished報文類似,是對字符串“server finished”進行計算,用於驗證server_write_key和server_write_MAC_secret。
APP Data:加密數據。
服務器端:首先根據client_write_key解密整個消息體,並對其中的實際數據部分進行HMAC(密鑰爲client_write_MAC_secret)並和客戶端發送過來的MAC進行比較,如果相同則認爲數據完整。
客戶端:首先根據server_write_key解密整個消息體,並對其中的實際數據部分進行HMAC(密鑰爲server_write_MAC_secret)並和客戶端發送過來的MAC進行比較,如果相同則認爲數據完整。
三、協議簇
上節是以TLS1.0爲基準進行說明,但是SSL/TLS協議簇內的協議之間有一定的差別。
3.1 SSL3.0
生成主密鑰
TLS1.0使用了PRF算法,其核心是分別用MD5和SHA分別計算的到Hash,並把MD5Hash和SHAHash相異或得到主密鑰;
SSL的計算方法:把SHA計算得到的Hash作爲MD5的輸入,計算得到16byte的Hash值,重複計算3次,把3次計算得到的3個16byte的Hash拼接成主密鑰。
生成計算密鑰
區別同上
數字簽名算法
對於加密數據的數字簽名算法。
TLS1.0使用了RFC2104定義的HMAC算法:HMAC:MAC = H(Key^oPad,H(Key^iPad , context))
SSLv3使用的MAC算法和HMAC算法類似:MAC = H(Key+oPad, H(Key+iPad , context))
3.2 TLS1.1
加密數據格式
TLS1.0中塊加密數據的格式爲
block-ciphered struct {
opaque content[TLSCompressed.length];
opaque MAC[CipherSpec.hash_size];
uint8 padding[GenericBlockCipher.padding_length];
uint8 padding_length;
} GenericBlockCipher;
TLS1.1塊加密數據的格式爲
block-ciphered struct {
opaque IV[CipherSpec.block_length];
opaque content[TLSCompressed.length];
opaque MAC[CipherSpec.hash_size];
uint8 padding[GenericBlockCipher.padding_length];
uint8 padding_length;
} GenericBlockCipher;
導致在塊加密數據解碼時有所不同。
3.3 TLS1.2
生成主密鑰
默認使用SHA256代替PRF
生成計算密鑰
默認使用SHA256代替PRF