ssl握手數據結構
ssl握手
SSL記錄頭(5字節)
- 字節0:記錄內容的類型
Content Type | Hex Code | Description |
---|---|---|
Change_Cipher_Spec | 0x14 | 指示加密方式的更改 |
Alert | 0x15 | 發出各種類型的錯誤信號 |
Handshake | 0x16 | 攜帶握手消息的記錄 |
Application_Data | 0x17 | 加密的應用數據 |
- 字節1和2:SSL版本(TLSv1是0x0301,SSLv3是0x0300)
- 字節3和4:記錄長度(不包括前面5字節)
握手消息頭(3字節)
- 字節0:握手類型
Handshake Type | Hex Code |
---|---|
hello_request | 0x00 |
client_hello | 0x01 |
server_hello | 0x02 |
certificate | 0x0b |
server_key_exchange | 0x0c |
certificate_request | 0x0d |
server_hello_done | 0x0e |
certificate_verify | 0x0f |
client_key_exchange | 0x10 |
finished | 0x14 |
- 字節1-3:握手消息長度(不包括前面3字節)
Client_Hello
告訴服務端客戶端期望的協議版本,算法套件和壓縮方法。還包括一個32字節的隨機數(client_random),由4字節的GMT Unix時間(從1970年開始的秒數)和28字節的隨機數組成
TLS1.2中增加了可選的Hello擴展,格式如下
struct {
ExtensionType extension_type;
opaque extension_data<0..2^16-1>;
} Extension;
擴展的類型以及對應的規範可以在此鏈接查看
Hello擴展類型
字節 | 長度 | 值 | 描述 |
---|---|---|---|
00 | 1 | 16 | 記錄內容類型 -- 握手消息 |
01-02 | 2 | 03 01 | SSL版本 -- TLSv1 |
03-04 | 2 | 00 61 | 記錄長度 |
05 | 1 | 01 | 握手類型 -- Client_Hello |
06-08 | 3 | 00 00 5d | 消息長度(0x61-4 = 0x5d) |
09-0A | 2 | 03 01 | 客戶端偏向的版本 -- TLSv1 |
0B-0E | 4 | 40 44 35 27 | GMT Unix時間 |
0C-2A | 28 | 5c ... 72 | 28字節隨機數,和4字節的時間組成client_random |
2B | 1 | 00 | Session ID長度 (恢復會話時使用) |
2C-2D | 2 | 00 36 | 加密套件長度 -- 27個 (每個2字節) |
2E-63 | 54 | .... | 27個算法套件(TLS1.2 0xFF結尾?) |
64 | 1 | 01 | 壓縮算法長度 |
65 | 1 | 00 | 壓縮算法: NULL |
算法套件對應的編號可以在此鏈接查看
算法套件
也可以使用openssl ciphers -V ‘ECDSA+AES+SM3‘
Server_Hello
告訴客戶端服務器的選擇,協議版本,算法套件,壓縮方法。也包括一個32字節的隨機數。
字節 | 長度 | 值 | 描述 |
---|---|---|---|
00 | 1 | 16 | 記錄內容類型 -- 握手消息 |
01-02 | 2 | 03 01 | SSL版本 -- TLSv1 |
03-04 | 2 | 00 2a | 記錄長度 |
05 | 1 | 02 | 握手類型 -- Server_Hello |
06-08 | 3 | 00 00 26 | 消息長度 |
09-0A | 2 | 03 01 | SSL版本 -- TLSv1 |
0B-0E | 4 | 40 44 35 27 | GMT Unix時間 |
0C-2A | 28 | cc ... b9 | 28字節隨機數,和4字節的時間組成server_random |
2B | 1 | 00 | Session ID長度 (恢復會話時使用) |
2C-2D | 2 | 00 16 | 選擇的加密套件 |
2E | 1 | 00 | 選擇的壓縮算法NULL |
擴展server hello不能出現擴展client hello中沒有出現的擴展類型。
Certificate
由正確順序的X509證書鏈組成,第一個是服務端證書,後續是簽發服務端證書的證書。客戶端使用服務端證書的公鑰來加密pre_master_secret或者驗證server_key_exchange。
字節 | 長度 | 值 | 描述 |
---|---|---|---|
00 | 1 | 16 | 記錄內容類型 -- 握手消息 |
01-02 | 2 | 03 01 | SSL版本 -- TLSv1 |
03-04 | 2 | 02 05 | 記錄長度 |
05 | 1 | 0b | 握手類型 -- Certificate |
06-08 | 3 | 00 02 01 | 消息長度 |
09-0B | 3 | 00 01 fe | 證書長度 |
證書 |
Server_Key_Exchange
Server_Hello_Done
空消息指示所有握手消息發送完畢,因為服務端可以在發送證書消息後發送一些可選的消息,所有需要。
字節 | 長度 | 值 | 描述 |
---|---|---|---|
00 | 1 | 16 | 記錄內容類型 -- 握手消息 |
01-02 | 2 | 03 01 | SSL版本 -- TLSv1 |
03-04 | 2 | 00 04 | 記錄長度 |
05 | 1 | 0e | 握手類型 -- Server_Hello_Done |
檢查最後3字節 |
Client_Key_Exchange
當使用RSA密鑰交換時包含pre_master_secret,包含2字節的版本和46字節的隨機數
字節 | 長度 | 值 | 描述 |
---|---|---|---|
00 | 1 | 16 | 記錄內容類型 -- 握手消息 |
01-02 | 2 | 03 01 | SSL版本 -- TLSv1 |
03-04 | 2 | 00 86 | 記錄長度 |
05 | 1 | 10 | 握手類型 -- Client_Key_Exchange |
06-08 | 3 | 00 00 82 | 消息長度 |
pre_master_secret(130字節,用服務端證書中的公鑰加密) |
Change_Cipher_Spec
Certificate_Verify
客戶端證書地顯式驗證,只有當證書有簽名能力時發送(除了那些包含固定DH參數的證書)
簽名的數據是從Client_Hello開始所有發送和接收的握手消息(包括消息的類型和長度),但不包括本條消息
Change_Cipher_Spec
Unknown_Handshaking_Message
Finish
此消息是第一個受保護的消息,接收方必須驗證內容正確。摘要計算包括所有握手消息但不包括本消息。 只是握手層可見的數據,不包括記錄層頭。(註意:change cipher spec, alerts和其他記錄類型都不是握手消息)
verify_data
PRF(master_secret, finished_label, MD5(handshake_messages) +
SHA-1(handshake_messages)) [0..11];
16 03 03 00 50 14 00 00 0c 09 ef c6 0d 6b 32 27 86 e4 73 0c b1
Application_Data
HTTP請求消息:Get /test.html HTTP/1.0
HTTP響應消息
Alert
ssl握手數據結構