SSL/TLS握手過程可以分成兩種類型:
1)SSL/TLS 雙向認證,就是雙方都會互相認證,也就是兩者之間將會交換認證。
2)SSL/TLS 單向認證,用戶端會證明伺服器端身份,而伺服器端不會去對用戶端身份進行驗證。
我們知道,握手過程實際上就是通訊雙方協商交換一個用於對稱式加密的密鑰的過程,而且握手過程是明文的。
這個過程實際上產生三個隨機數:client random, server random, pre-master secret. 參考圖解SSL/TLS協議 .
前兩個隨機數都是明文傳送的,只有pre-master secret是加密的(RSA或者DH)。
一般產生認證的時候,簽名演算法可以選擇RSA或者DSA演算法。
如果server使用RSA認證,RSA即可以用作簽名也可以用作不對稱式加密,pre-master secret就是用server的RSA認證中包含的公開金鑰加密的。
如果server使用DSA認證,DSA只能用作簽名,所以還需要使用DH演算法來交換密鑰。
以下是其流程圖(摘自rfc5246),括弧中的步驟是可選的。
如果是單向認證,那麼藍色字型部分是不需要的。
4 server_key_exchange這一步只有在選擇了某些金鑰交換演算法例如DH演算法的時候才需要。
| Client |
Server |
| 1 Client Hello |
|
|
2 Server Hello 3 certificate 4 (server_key_exchange) 5 (certificate_request) 6 server_hello_done |
7 (certificate) 8 client_key_exchange 9 (certifiate_verify) 10 change_cypher_spec ----finished---- |
|
|
11 change_cypher_spec ----finished---- |
下面使用wireshark抓取握手過程的報文。server/client使用JAVA7/JSSE編碼。 server認證簽名演算法RSA-雙向認證
可見包括了除了4以外的所有步驟。因為採取了RSA演算法,所以步驟4是不需要的。
(一) 首先,用戶端向伺服器提供以下資訊
client_hello
(1)支援的協議版本,比如TLS 1.0
(2)支援的密碼編譯演算法(Cipher Specs)
(3)用戶端產生的隨機數1(Challenge),稍後用於產生"對話密鑰"。
(二)伺服器回答給用戶端以下資訊
server_hello
(1) 確認使用的協議版本
(2) 伺服器產生的隨機數2,稍後用於產生"對話密鑰"
(3) session id
(4) 確認使用的密碼編譯演算法
certificate
伺服器憑證
server_key_exchange
如果是DH演算法,這裡發送伺服器使用的DH參數。RSA演算法不需要這一步。
certificate_request
要求用戶端提供認證,包括
(1) 用戶端可以提供的認證類型
(2)伺服器接受的認證distinguished name列表,可以是root CA或者subordinate CA。如果伺服器配置了trust keystore, 這裡會列出所有在trust keystore中的認證的distinguished name。
server_hello_done
server hello結束
(三)用戶端發送給伺服器
certificate
用戶端認證
client_key_exchange
包含pre-master secret。用戶端產生第三個隨機數。如果是採用RSA演算法,會產生一個48位元組隨機數,然後用server的公開金鑰加密之後再放入報文中;如果是DH演算法,這裡發送的就是用戶端的DH參數,之後伺服器和用戶端根據DH演算法,各自計算出相同的pre-master secret。
certificate_verify
發送使用用戶端認證給到這一步為止收到和發送的所有握手訊息簽名結果。
change_cipher_spec
用戶端通知伺服器開始使用加密方式發送報文。用戶端使用上面的3個隨機數client random, server random, pre-master secret, 計算出48位元組的master secret, 這個就是對稱式加密演算法的密鑰。
finished
用戶端發送第一個加密報文。使用HMAC演算法計算收到和發送的所有握手訊息的摘要,然後通過RFC5246中定義的一個偽函數PRF計算出結果,加密後發送。
(四) 伺服器發送給用戶端
伺服器端發送change_cipher_spec和finished訊息。到這裡握手結束。
server認證簽名演算法DSA-雙向認證
下面是一個server認證採用DSA演算法的握手過程。由於採用了DH演算法交換密鑰,多了server_key_exchange這一步。
server認證簽名演算法RSA-單向認證
和雙向認證相比,server端少了certificate_request,client端少了certificate 和 certificate_verify。