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