一、DTLS -PSK
PSK 是DTLS 定義的密鑰交換方案之一,相對於公鑰證書方案(如 ECDHA_RSA) 來說,其具備更加輕量化、高效的優點;
而目前 PSK方案應用也比較廣泛。 關於DTLS協議可以看看前面的文章 DTLS要點解析
本次通過模擬的DTLS程序,對DTLS-PSK 握手流程進行抓包分析,以期加深對協議本身的理解。
二、完整握手
流程
Client Server
------ ------
1.ClientHello -------->
<-------- 2..HelloVerifyRequest
(contains cookie)
3.ClientHello -------->
(with cookie)
4.ServerHello
<-------- 5.ServerHelloDone
6.ClientKeyExchange
7.ChangeCipherSpec
8.Finished -------->
9.ChangeCipherSpec
<-------- 10.Finished
Application Data <-------> Application Data
步驟解析
~1. Client 發送ClientHello
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: localhost/127.0.0.1:5684
Version: 254, 253
Epoch: 0
Sequence Number: 0
Length: 82
Fragment:
Handshake Protocol
Type: CLIENT_HELLO (1)
Peer: localhost/127.0.0.1:5684
Message Sequence No: 0
Fragment Offset: 0
Fragment Length: 70
Length: 70
Version: 254, 253
Random:
GMT Unix Time: Mon Jan 30 22:45:32 CST 2017
Random Bytes: 4B 8B 3C CF 0F 62 57 99 94 E9 86 0A 46 68 BF 44 00 D1 34 45 FC 81 C3 AC BC 55 7E DB
Session ID Length: 0
Cookie Length: 0
Cipher Suites Length: 4
Cipher Suites (2 suites)
Cipher Suite: TLS_PSK_WITH_AES_128_CCM_8
Cipher Suite: TLS_PSK_WITH_AES_128_CBC_SHA256
Compression Methods Length: 1
Compression Methods (1 method)
Compression Method: NULL
Extensions Length: 24
Extension: elliptic_curves (10)
Length: 8
Elliptic Curves Length: 6
Elliptic Curves (3 curves):
Elliptic Curve: secp256r1 (23)
Elliptic Curve: secp384r1 (24)
Elliptic Curve: secp521r1 (25)
Extension: ec_point_formats (11)
Length: 2
EC point formats length: 1
Elliptic Curves Point Formats (1):
EC point format: uncompressed (0)
Extension: server_certificate_type (20)
Server certificate type: RAW_PUBLIC_KEY
===============================================================
此時沒有攜帶Cookie,SessionID未生成;
Cipher Suites 攜帶了用於協商的算法集。
~2. Server 回復HelloVerifyRequest
Handshake Protocol
Type: HELLO_VERIFY_REQUEST (3)
Peer: localhost/127.0.0.1:5684
Message Sequence No: 0
Fragment Offset: 0
Fragment Length: 35
Length: 35
Server Version: 254, 253
Cookie Length: 32
Cookie: 77 25 7E 96 9E BD 39 42 94 5F 27 6C 8A 6D 9D D2 1A C9 A3 B8 62 1A 34 86 76 1D D7 AA F4 28 98 6D
Request中攜帶了32字節的Cookie。
~3. Client 再次發送ClientHello
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: localhost/127.0.0.1:5684
Version: 254, 253
Epoch: 0
Sequence Number: 1
Length: 114
Fragment:
Handshake Protocol
Type: CLIENT_HELLO (1)
Peer: localhost/127.0.0.1:5684
Message Sequence No: 1
Fragment Offset: 0
Fragment Length: 102
Length: 102
Version: 254, 253
Random:
GMT Unix Time: Mon Jan 30 22:45:32 CST 2017
Random Bytes: 4B 8B 3C CF 0F 62 57 99 94 E9 86 0A 46 68 BF 44 00 D1 34 45 FC 81 C3 AC BC 55 7E DB
Session ID Length: 0
Cookie Length: 32
Cookie: 77 25 7E 96 9E BD 39 42 94 5F 27 6C 8A 6D 9D D2 1A C9 A3 B8 62 1A 34 86 76 1D D7 AA F4 28 98 6D
Cipher Suites Length: 4
Cipher Suites (2 suites)
Cipher Suite: TLS_PSK_WITH_AES_128_CCM_8
Cipher Suite: TLS_PSK_WITH_AES_128_CBC_SHA256
Compression Methods Length: 1
Compression Methods (1 method)
Compression Method: NULL
Extensions Length: 24
Extension: elliptic_curves (10)
Length: 8
Elliptic Curves Length: 6
Elliptic Curves (3 curves):
Elliptic Curve: secp256r1 (23)
Elliptic Curve: secp384r1 (24)
Elliptic Curve: secp521r1 (25)
Extension: ec_point_formats (11)
Length: 2
EC point formats length: 1
Elliptic Curves Point Formats (1):
EC point format: uncompressed (0)
Extension: server_certificate_type (20)
Server certificate type: RAW_PUBLIC_KEY
===============================================================
本次攜帶了服務端返回的Cookie值。
~4. Server 回復ServerHello
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: /127.0.0.1:64688
Version: 254, 253
Epoch: 0
Sequence Number: 1
Length: 82
Fragment:
Handshake Protocol
Type: SERVER_HELLO (2)
Peer: /127.0.0.1:64688
Message Sequence No: 1
Fragment Offset: 0
Fragment Length: 70
Length: 70
Server Version: 254, 253
Random:
GMT Unix Time: Mon Jan 30 22:45:32 CST 2017
Random Bytes: AB AB 69 55 C4 2E 1F B0 8D B7 FE 7F EA 36 E5 18 6A FD 4D C8 19 4C 73 63 D3 19 B5 E0
Session ID Length: 32
Session ID: 58 8F 51 8C 2A 2A B5 DC 14 9C AB D3 F2 EE BA 25 78 80 47 25 A7 93 35 34 00 D5 CD 53 2C EC B3 D4
Cipher Suite: TLS_PSK_WITH_AES_128_CCM_8
Compression Method: NULL
Extensions Length: 0
===============================================================
此時生成了32字節的 SessionID;
CipherSute 指明了即將采用的密鑰算法集;
~5. Server 回復ServerHelloDone
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: /127.0.0.1:64688
Version: 254, 253
Epoch: 0
Sequence Number: 2
Length: 12
Fragment:
Handshake Protocol
Type: SERVER_HELLO_DONE (14)
Peer: /127.0.0.1:64688
Message Sequence No: 2
Fragment Offset: 0
Fragment Length: 0
Length: 0
===============================================================
Server 通知ServerHello結束。
~6. Client 發送ClientKeyExchange
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: localhost/127.0.0.1:5684
Version: 254, 253
Epoch: 0
Sequence Number: 2
Length: 23
Fragment:
Handshake Protocol
Type: CLIENT_KEY_EXCHANGE (16)
Peer: localhost/127.0.0.1:5684
Message Sequence No: 2
Fragment Offset: 0
Fragment Length: 11
Length: 11
PSK Identity: 012345678
===============================================================
PSK Identity 用於標識終端ID,后續雙方根據該ID找到終端預置的PSK用於計算密鑰;
~7. Client 發送ChangeCipherSpec
==[ DTLS Record ]==============================================
Content Type: Change Cipher Spec (20)
Peer address: localhost/127.0.0.1:5684
Version: 254, 253
Epoch: 0
Sequence Number: 3
Length: 1
Fragment:
Change Cipher Spec Message
===============================================================
Client 表示已經確認算法和密鑰。
~8. Client 發送Finish
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: localhost/127.0.0.1:5684
Version: 254, 253
Epoch: 1
Sequence Number: 0
Length: 40
Fragment:
Handshake Protocol
Type: FINISHED (20)
Peer: localhost/127.0.0.1:5684
Message Sequence No: 3
Fragment Offset: 0
Fragment Length: 12
Length: 12
Verify Data: BC 00 D7 F6 6F E5 A4 B4 0D 8B 5C 8A
===============================================================
Client 表示握手完成,其中Verify Data是由動態密鑰計算得出的摘要,用於Server端驗證。
~9. Server 發送ChangeCipherSpec
==[ DTLS Record ]==============================================
Content Type: Change Cipher Spec (20)
Peer address: /127.0.0.1:64688
Version: 254, 253
Epoch: 0
Sequence Number: 3
Length: 1
Fragment:
Change Cipher Spec Message
===============================================================
Server 表示已經確認算法和密鑰。
~10. Server 發送Finish
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: /127.0.0.1:64688
Version: 254, 253
Epoch: 1
Sequence Number: 0
Length: 40
Fragment:
Handshake Protocol
Type: FINISHED (20)
Peer: /127.0.0.1:64688
Message Sequence No: 3
Fragment Offset: 0
Fragment Length: 12
Length: 12
Verify Data: EC C9 5E 4E 24 BE 77 78 CB F5 20 54
===============================================================
Server 表示握手完成,其中Verify Data是由動態密鑰計算得出的摘要,用於Client端驗證。
至此,完整的PSK 握手流程已經結束,接下來執行會話恢復的場景。
三、會話恢復
流程
Client Server
------ ------
1.ClientHello -------->
<-------- 2..HelloVerifyRequest
(contains cookie)
3.ClientHello -------->
(with cookie)
4.ServerHello
5.ChangeCipherSpec
<-------- 6.Finished
7.ChangeCipherSpec
8.Finished -------->
Application Data <-------> Application Data
步驟解析
~1. Client 發送ClientHello
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: /127.0.0.1:5684
Version: 254, 253
Epoch: 0
Sequence Number: 0
Length: 115
Fragment:
Handshake Protocol
Type: CLIENT_HELLO (1)
Peer: /127.0.0.1:5684
Message Sequence No: 0
Fragment Offset: 0
Fragment Length: 103
Length: 103
Version: 254, 253
Random:
GMT Unix Time: Tue Jan 31 00:02:05 CST 2017
Random Bytes: B6 28 F7 76 FE C1 B9 7A 87 CE D9 81 2D C3 9A AA 07 F8 69 2D 36 A3 B3 A2 1F 47 E1 FF
Session ID Length: 32
Session ID: 58 8F 63 71 DE B4 87 9A C0 0B 67 BB 16 7F 33 1C B6 FF E2 74 74 D9 EB 58 D4 78 44 BA 4C 22 42 38
Cookie Length: 0
Cipher Suites Length: 4
Cipher Suites (2 suites)
Cipher Suite: TLS_NULL_WITH_NULL_NULL
Cipher Suite: TLS_PSK_WITH_AES_128_CCM_8
Compression Methods Length: 2
Compression Methods (2 method)
Compression Method: NULL
Compression Method: NULL
Extensions Length: 24
Extension: elliptic_curves (10)
Length: 8
Elliptic Curves Length: 6
Elliptic Curves (3 curves):
Elliptic Curve: secp256r1 (23)
Elliptic Curve: secp384r1 (24)
Elliptic Curve: secp521r1 (25)
Extension: ec_point_formats (11)
Length: 2
EC point formats length: 1
Elliptic Curves Point Formats (1):
EC point format: uncompressed (0)
Extension: server_certificate_type (20)
Server certificate type: RAW_PUBLIC_KEY
===============================================================
此時SessionID已經存在,但Cookie為空,仍然需要經過一次HelloVerify。
~2.Server 發送HelloVerifyRequest
Handshake Protocol
Type: HELLO_VERIFY_REQUEST (3)
Peer: /127.0.0.1:5684
Message Sequence No: 0
Fragment Offset: 0
Fragment Length: 35
Length: 35
Server Version: 254, 253
Cookie Length: 32
Cookie: 67 6B 86 62 06 F6 A4 3D 31 59 B1 82 80 39 23 76 C6 2C E2 FC E1 7F 41 E8 EE 13 6C 12 A6 76 7B C5
Server 發送了32字節的Cookie值
~3. Client 再次發送ClientHello
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: /127.0.0.1:5684
Version: 254, 253
Epoch: 0
Sequence Number: 1
Length: 147
Fragment:
Handshake Protocol
Type: CLIENT_HELLO (1)
Peer: /127.0.0.1:5684
Message Sequence No: 1
Fragment Offset: 0
Fragment Length: 135
Length: 135
Version: 254, 253
Random:
GMT Unix Time: Tue Jan 31 00:02:05 CST 2017
Random Bytes: B6 28 F7 76 FE C1 B9 7A 87 CE D9 81 2D C3 9A AA 07 F8 69 2D 36 A3 B3 A2 1F 47 E1 FF
Session ID Length: 32
Session ID: 58 8F 63 71 DE B4 87 9A C0 0B 67 BB 16 7F 33 1C B6 FF E2 74 74 D9 EB 58 D4 78 44 BA 4C 22 42 38
Cookie Length: 32
Cookie: 67 6B 86 62 06 F6 A4 3D 31 59 B1 82 80 39 23 76 C6 2C E2 FC E1 7F 41 E8 EE 13 6C 12 A6 76 7B C5
Cipher Suites Length: 4
Cipher Suites (2 suites)
Cipher Suite: TLS_NULL_WITH_NULL_NULL
Cipher Suite: TLS_PSK_WITH_AES_128_CCM_8
Compression Methods Length: 2
Compression Methods (2 method)
Compression Method: NULL
Compression Method: NULL
Extensions Length: 24
Extension: elliptic_curves (10)
Length: 8
Elliptic Curves Length: 6
Elliptic Curves (3 curves):
Elliptic Curve: secp256r1 (23)
Elliptic Curve: secp384r1 (24)
Elliptic Curve: secp521r1 (25)
Extension: ec_point_formats (11)
Length: 2
EC point formats length: 1
Elliptic Curves Point Formats (1):
EC point format: uncompressed (0)
Extension: server_certificate_type (20)
Server certificate type: RAW_PUBLIC_KEY
===============================================================
此時Cookie和SessionID都不為空。
~4. Server 發送ServerHello
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: /127.0.0.1:54595
Version: 254, 253
Epoch: 0
Sequence Number: 1
Length: 82
Fragment:
Handshake Protocol
Type: SERVER_HELLO (2)
Peer: /127.0.0.1:54595
Message Sequence No: 1
Fragment Offset: 0
Fragment Length: 70
Length: 70
Server Version: 254, 253
Random:
GMT Unix Time: Tue Jan 31 00:02:05 CST 2017
Random Bytes: 6B 21 0D B0 A3 33 A3 49 65 0E D9 D1 DB 0E 62 74 51 EE 1B E1 CC 37 1E FD 8C 67 39 00
Session ID Length: 32
Session ID: 58 8F 63 71 DE B4 87 9A C0 0B 67 BB 16 7F 33 1C B6 FF E2 74 74 D9 EB 58 D4 78 44 BA 4C 22 42 38
Cipher Suite: TLS_PSK_WITH_AES_128_CCM_8
Compression Method: NULL
===============================================================
~5. Server 發送ChangeCipherSpec
==[ DTLS Record ]==============================================
Content Type: Change Cipher Spec (20)
Peer address: /127.0.0.1:54595
Version: 254, 253
Epoch: 0
Sequence Number: 2
Length: 1
Fragment:
Change Cipher Spec Message
===============================================================
Server 表示已經確認算法和密鑰。
~6. Server 發送Finish
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: /127.0.0.1:54595
Version: 254, 253
Epoch: 1
Sequence Number: 0
Length: 40
Fragment:
Handshake Protocol
Type: FINISHED (20)
Peer: /127.0.0.1:54595
Message Sequence No: 2
Fragment Offset: 0
Fragment Length: 12
Length: 12
Verify Data: D7 8F CA EC 97 B7 96 A3 CD 5E 5C 97
===============================================================
Server 表示握手完成,其中VerifyData 用於Client端驗證。
~7. Client 發送ChangeCipherSpec
==[ DTLS Record ]==============================================
Content Type: Change Cipher Spec (20)
Peer address: /127.0.0.1:5684
Version: 254, 253
Epoch: 0
Sequence Number: 2
Length: 1
Fragment:
Change Cipher Spec Message
===============================================================
Client 表示已經確認算法和密鑰。
~8. Client 發送Finish
==[ DTLS Record ]==============================================
Content Type: Handshake (22)
Peer address: /127.0.0.1:5684
Version: 254, 253
Epoch: 1
Sequence Number: 0
Length: 40
Fragment:
Handshake Protocol
Type: FINISHED (20)
Peer: /127.0.0.1:5684
Message Sequence No: 2
Fragment Offset: 0
Fragment Length: 12
Length: 12
Verify Data: 3F 86 FC 45 D8 41 A6 BE BD 54 C2 7A
===============================================================
Client 表示握手完成,其中VerifyData 用於Server端驗證。
至此,會話恢復(Resuming)流程分析完畢。
四、相關參考
Scadium 是一個純Java語言的DTLS實現,可支持DTLS 1.2版本。
目前其被納入 Californium項目(Coap技術框架),項目地址為:
https://github.com/eclipse/californium/tree/master/scandium-core
關於DTLS的技術紀要:
http://www.cnblogs.com/littleatp/p/6358261.html
TLS_PSK 標准定義:
https://tools.ietf.org/html/rfc4279