這篇blog相似Example Handshake Traces for TLS 1.3. 人肉trace/verify一個典型的TLS 1.2握手.
由於hash值沒法反推, 理解錯誤時很難debug. 讀rfc文檔的效率不如直接閱讀代碼. Finished消息以後的內容還沒有驗證完畢.html
# HTTPS server server { listen 443 ssl; server_name localhost; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key; ssl_protocols TLSv1.2; location / { root html; index index.html index.htm; } }
openssl提示, private key至少是512 bits.node
ubuntu# openssl req -new -newkey rsa:512 -nodes -keyout server.key -out server.csr
私鑰內容會用於下面的計算.nginx
ubuntu# openssl rsa -text -in server.key Private-Key: (512 bit) modulus: 00:bf:ec:7d:37:cf:10:f1:94:8a:e1:ca:bf:9b:9c: 94:13:35:30:75:5e:d0:27:6a:9f:e6:d5:2a:06:0d: 34:80:17:18:9a:4e:87:0b:60:7f:38:9e:d4:04:49: 13:b9:b8:45:c0:ad:83:53:70:34:4d:0b:3e:17:4e: a8:d6:3f:36:79 publicExponent: 65537 (0x10001) privateExponent: 30:f9:14:7e:b0:2c:bf:a8:4a:c4:10:eb:51:b6:e3: a5:ff:15:8d:6d:93:29:eb:b0:3f:c3:b7:04:72:4c: 2a:3e:c9:5d:a3:ae:fb:27:b0:7b:74:b4:08:26:27: c6:f0:34:24:d8:21:32:9f:fe:c1:90:45:8b:0a:80: 67:b4:77:6d prime1: 00:de:d1:50:42:ba:8a:8b:64:47:7a:e9:83:02:a7: e0:8d:3b:84:56:61:ce:1a:7d:48:6e:ad:97:4d:85: c7:be:1b prime2: 00:dc:81:61:64:c5:90:f6:b4:87:1e:1f:c6:d1:62: cb:03:7f:d0:66:ff:1d:e8:7e:bf:ce:e3:3f:70:b6: 4c:96:fb exponent1: 34:4f:7b:c2:4e:bd:1c:00:8c:ef:84:46:e7:a6:b6: 07:32:43:dd:6b:d4:d1:4f:3c:64:0f:89:08:00:32: 66:a5 exponent2: 00:c4:ed:23:2e:dd:26:7e:bd:71:22:5d:1c:b1:68: fa:87:d0:81:2d:4a:cf:ca:10:50:7a:93:06:d8:41: 66:9b:3b coefficient: 47:a4:10:03:d0:b3:83:62:33:95:be:5c:eb:2b:4c: 5b:87:d4:89:4f:5d:f8:15:a2:4c:7d:5a:58:3b:00: 9f:41 writing RSA key -----BEGIN RSA PRIVATE KEY----- MIIBOgIBAAJBAL/sfTfPEPGUiuHKv5uclBM1MHVe0Cdqn+bVKgYNNIAXGJpOhwtg fzie1ARJE7m4RcCtg1NwNE0LPhdOqNY/NnkCAwEAAQJAMPkUfrAsv6hKxBDrUbbj pf8VjW2TKeuwP8O3BHJMKj7JXaOu+yewe3S0CCYnxvA0JNghMp/+wZBFiwqAZ7R3 bQIhAN7RUEK6iotkR3rpgwKn4I07hFZhzhp9SG6tl02Fx74bAiEA3IFhZMWQ9rSH Hh/G0WLLA3/QZv8d6H6/zuM/cLZMlvsCIDRPe8JOvRwAjO+ERuemtgcyQ91r1NFP PGQPiQgAMmalAiEAxO0jLt0mfr1xIl0csWj6h9CBLUrPyhBQepMG2EFmmzsCIEek EAPQs4NiM5W+XOsrTFuH1IlPXfgVokx9Wlg7AJ9B -----END RSA PRIVATE KEY-----
ubuntu# openssl x509 -req -in server.csr -signkey server.key -out server.crt Signature ok subject=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd Getting Private key
只有用RSA做爲密鑰加密算法時, 才能僅依據RSA私鑰解密整個通訊內容. 因此要記錄ssl握手日誌.
握手日誌格式:Key_Log_Format
在bashrc裏export的方式對我無效. 因而直接在啓動命令行上export.git
CLIENT_RANDOM 40d527ab4688ac43d40aad7ddb955053c6fc3abaf16511a74ef0894214b404c7 84d061c5ef4bf433f4f897cb2fcf8a53896e8d0ae7d5adc378b0e5c42cfc9abe43513bfe2408b0ab30217fabd6474c7b
tls v1.2 見https://tools.ietf.org/html/rfc5246算法
Client Server ClientHello --------> ServerHello Certificate\* ServerKeyExchange\* CertificateRequest\* <-------- ServerHelloDone Certificate\* ClientKeyExchange CertificateVerify\* \[ChangeCipherSpec\] Finished --------> \[ChangeCipherSpec\] <-------- Finished Application Data <-------> Application Data Figure 1. Message flow for a full handshake
該步驟徹底是明文.chrome
struct { ProtocolVersion client\_version; Random random; SessionID session\_id; CipherSuite cipher\_suites<2..2^16-2>; CompressionMethod compression\_methods<1..2^8-1>; select (extensions\_present) { case false: struct {}; case true: Extension extensions<0..2^16-1>; }; } ClientHello;
該步驟徹底是明文ubuntu
struct { ProtocolVersion server\_version; Random random; SessionID session\_id; CipherSuite cipher\_suite; CompressionMethod compression\_method; select (extensions\_present) { case false: struct {}; case true: Extension extensions<0..2^16-1>; }; } ServerHello;
opaque ASN.1Cert<1..2^24-1>; struct { ASN.1Cert certificate\_list<0..2^24-1>; } Certificate;
能夠看到,發給客戶端挑選的證書,只有前面生成的部分.bash
copy as a Hex Streamsession
3082017c30820126020900f222ec913dca89ff300d06092a864886f70d01010b05003045310b30090603550406130241553113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464301e170d3139313231363133313431305a170d3230303131353133313431305a3045310b30090603550406130241553113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464305c300d06092a864886f70d0101010500034b003048024100bfec7d37cf10f1948ae1cabf9b9c94133530755ed0276a9fe6d52a060d348017189a4e870b607f389ed4044913b9b845c0ad835370344d0b3e174ea8d63f36790203010001300d06092a864886f70d01010b0500034100781581578ce8a601dedb1a0469771843aa47f7a493c4e5e459b978507399faa9b043cbda16c832bc522ea035a47280e991048bfa425b499a58a9057c3ef54740
~/tls_test » cat server.crt | grep -v "CERTIFICATE" | base64 -d | xxd 00000000: 3082 017c 3082 0126 0209 00f2 22ec 913d 0..|0..&...."..= 00000010: ca89 ff30 0d06 092a 8648 86f7 0d01 010b ...0...*.H...... 00000020: 0500 3045 310b 3009 0603 5504 0613 0241 ..0E1.0...U....A 00000030: 5531 1330 1106 0355 0408 0c0a 536f 6d65 U1.0...U....Some 00000040: 2d53 7461 7465 3121 301f 0603 5504 0a0c -State1!0...U... 00000050: 1849 6e74 6572 6e65 7420 5769 6467 6974 .Internet Widgit 00000060: 7320 5074 7920 4c74 6430 1e17 0d31 3931 s Pty Ltd0...191 00000070: 3231 3631 3331 3431 305a 170d 3230 3031 216131410Z..2001 00000080: 3135 3133 3134 3130 5a30 4531 0b30 0906 15131410Z0E1.0.. 00000090: 0355 0406 1302 4155 3113 3011 0603 5504 .U....AU1.0...U. 000000a0: 080c 0a53 6f6d 652d 5374 6174 6531 2130 ...Some-State1!0 000000b0: 1f06 0355 040a 0c18 496e 7465 726e 6574 ...U....Internet 000000c0: 2057 6964 6769 7473 2050 7479 204c 7464 Widgits Pty Ltd 000000d0: 305c 300d 0609 2a86 4886 f70d 0101 0105 0\0...*.H....... 000000e0: 0003 4b00 3048 0241 00bf ec7d 37cf 10f1 ..K.0H.A...}7... 000000f0: 948a e1ca bf9b 9c94 1335 3075 5ed0 276a .........50u^.'j 00000100: 9fe6 d52a 060d 3480 1718 9a4e 870b 607f ...*..4....N..`. 00000110: 389e d404 4913 b9b8 45c0 ad83 5370 344d 8...I...E...Sp4M 00000120: 0b3e 174e a8d6 3f36 7902 0301 0001 300d .>.N..?6y.....0. 00000130: 0609 2a86 4886 f70d 0101 0b05 0003 4100 ..*.H.........A. 00000140: 7815 8157 8ce8 a601 dedb 1a04 6977 1843 x..W........iw.C 00000150: aa47 f7a4 93c4 e5e4 59b9 7850 7399 faa9 .G......Y.xPs... 00000160: b043 cbda 16c8 32bc 522e a035 a472 80e9 .C....2.R..5.r.. 00000170: 9104 8bfa 425b 499a 58a9 057c 3ef5 4740 ....B[I.X..|>.G@
實際使用的算法是dhe_rsa, 參照ServerHello中的Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.app
struct { opaque dh_p<1..2^16-1>; opaque dh_g<1..2^16-1>; opaque dh_Ys<1..2^16-1>; } ServerDHParams; /* Ephemeral DH parameters */ dh_p The prime modulus used for the Diffie-Hellman operation. dh_g The generator used for the Diffie-Hellman operation. dh_Ys The server's Diffie-Hellman public value (g^X mod p). struct { select (KeyExchangeAlgorithm) { case dh_anon: ServerDHParams params; case dhe_dss: case dhe_rsa: ServerDHParams params; digitally-signed struct { opaque client_random[32]; opaque server_random[32]; ServerDHParams params; } signed_params; case rsa: case dh_dss: case dh_rsa: struct {} ; /* message is omitted for rsa, dh_dss, and dh_rsa */ /* may be extended, e.g., for ECDH -- see [TLSECC] */ }; } ServerKeyExchange; params The server's key exchange parameters. signed_params For non-anonymous key exchanges, a signature over the server's key exchange parameters.
client_random:
40d527ab4688ac43d40aad7ddb955053c6fc3abaf16511a74ef0894214b404c7
server_random:
830fe44c4f3d85e3d95f6b0043de6f87e2e6613625d39fd5fa42d85a34fd5580
server dh params:
030017410433bad3063e435c706c39a994d83f1d69bb30cfd12150d5bb4e16584d1751ce5cdeefaefa57b2f9cced0f9f86b2ced66f0e00ee2c9d21b7a4a77351299c984063
all data for sign:
這裏注意, 簽名的內容和rfc文檔中徹底一致, 提取ServerDHParams時建議整個copy出來, 再剔除掉Signature Algorithm Signature Length, Signature等bytes.
~/tls_test » echo -n ~/tls_test » echo -n "40d527ab4688ac43d40aad7ddb955053c6fc3abaf16511a74ef0894214b404c7830fe44c4f3d85e3d95f6b0043de6f87e2e6613625d39fd5fa42d85a34fd5580030017410433bad3063e435c706c39a994d83f1d69bb30cfd12150d5bb4e16584d1751ce5cdeefaefa57b2f9cced0f9f86b2ced66f0e00ee2c9d21b7a4a77351299c984063" | xxd -r -p > all_random ~/tls_test » cat all_random | xxd 00000000: 40d5 27ab 4688 ac43 d40a ad7d db95 5053 @.'.F..C...}..PS 00000010: c6fc 3aba f165 11a7 4ef0 8942 14b4 04c7 ..:..e..N..B.... 00000020: 830f e44c 4f3d 85e3 d95f 6b00 43de 6f87 ...LO=..._k.C.o. 00000030: e2e6 6136 25d3 9fd5 fa42 d85a 34fd 5580 ..a6%....B.Z4.U. 00000040: 0300 1741 0433 bad3 063e 435c 706c 39a9 ...A.3...>C\pl9. 00000050: 94d8 3f1d 69bb 30cf d121 50d5 bb4e 1658 ..?.i.0..!P..N.X 00000060: 4d17 51ce 5cde efae fa57 b2f9 cced 0f9f M.Q.\....W...... 00000070: 86b2 ced6 6f0e 00ee 2c9d 21b7 a4a7 7351 ....o...,.!...sQ 00000080: 299c 9840 63 )..@c
7703282574ba1e59284b3853ab108f06d2cf072cc9cabf89787fe8a7fad450301fe3c6091126ab4a967f1dcf8d96857ebd7bca27bce1ca5fe08c1316531b58f3
在wireshark中將EC Diffie-Hellman Server Params的Signature使用Export Packet Bytes導出到文件.
以後用openssl驗證簽名. 能夠看到驗證是成功的.
~/tls_test » cat server_exchange_signature| xxd 00000000: 7703 2825 74ba 1e59 284b 3853 ab10 8f06 w.(%t..Y(K8S.... 00000010: d2cf 072c c9ca bf89 787f e8a7 fad4 5030 ...,....x.....P0 00000020: 1fe3 c609 1126 ab4a 967f 1dcf 8d96 857e .....&.J.......~ 00000030: bd7b ca27 bce1 ca5f e08c 1316 531b 58f3 .{.'..._....S.X.
~/tls_test » openssl rsautl -verify -inkey server.pem -in server_exchange_signature -pubin | xxd 00000000: 3031 300d 0609 6086 4801 6503 0402 0105 010...`.H.e..... 00000010: 0004 2029 35e7 0121 926d 2e13 d655 9943 .. )5..!.m...U.C 00000020: 8598 6c0c ac36 beb6 17ab f268 86d7 8c90 ..l..6.....h.... 00000030: 6058 b4 `X.
正向計算哈希值, 和verify的結果恰好吻合. 前面還有一些疑似的magic number. 由於每次sign verify, 都有相似的字節. 這裏不追究這些magic number的細節.
~/tls_test » sha256sum all_random 2935e70121926d2e13d655994385986c0cac36beb617abf26886d78c906058b4 all_random
~/tls_test » echo "abcd" >> tt ~/tls_test » openssl dgst -sha256 -sign server.key -out all_random_signature tt ~/tls_test » openssl dgst -sha256 -sign server.key -out tt_signature tt ~/tls_test » openssl rsautl -verify -inkey server.pem -in tt_signature -pubin | xxd 00000000: 3031 300d 0609 6086 4801 6503 0402 0105 010...`.H.e..... 00000010: 0004 20fc 4b5f d681 6f75 a7c8 1fc8 eaa9 .. .K_..ou...... 00000020: 499d 6a29 9bd8 0339 7166 e8c4 cf92 80b8 I.j)...9qf...... 00000030: 01d6 2c .., ------------------------------------------------------------ ~/tls_test » sha256sum tt fc4b5fd6816f75a7c81fc8eaa9499d6a299bd803397166e8c4cf9280b801d62c tt
告訴client能夠作key exchange了.
Meaning of this message: This message means that the server is done sending messages to support the key exchange, and the client can proceed with its phase of the key exchange. Upon receipt of the ServerHelloDone message, the client SHOULD verify that the server provided a valid certificate, if required, and check that the server hello parameters are acceptable.
struct { select (KeyExchangeAlgorithm) { case rsa: EncryptedPreMasterSecret; case dhe_dss: case dhe_rsa: case dh_dss: case dh_rsa: case dh_anon: ClientDiffieHellmanPublic; } exchange_keys; } ClientKeyExchange;
發送的是ClientDiffieHellmanPublic, 若是是rsa, 則有一個可用前面私鑰直接解密的pre master secret.
The ChangeCipherSpec message is sent by both the client and the
server to notify the receiving party that subsequent records will be
protected under the newly negotiated CipherSpec and keys.
Finished用於驗證加密/壓縮是正確的.
Meaning of this message: The Finished message is the first one protected with the just negotiated algorithms, keys, and secrets. Recipients of Finished messages MUST verify that the contents are correct. Once a side has sent its Finished message and received and validated the Finished message from its peer, it may begin to send and receive application data over the connection. Structure of this message: struct { opaque verify_data[verify_data_length]; } Finished; verify_data PRF(master_secret, finished_label, Hash(handshake_messages)) [0..verify_data_length-1];
這裏對不上.
struct { opaque verify_data[verify_data_length]; } Finished; verify_data PRF(master_secret, finished_label, Hash(handshake_messages)) [0..verify_data_length-1];
84d061c5ef4bf433f4f897cb2fcf8a53896e8d0ae7d5adc378b0e5c42cfc9abe43513bfe2408b0ab30217fabd6474c7b
~/tls_test/master_key » echo -n "client finished" | xxd -p 636c69656e742066696e6973686564
以下hex string包含圖中的Client Hello, Server Hello, Certificate Server key Exchange, Server Hello Done, Client Key Exchange, 具體看rfc文檔對handshake_messages的解釋:
16030100c0010000bc030340d527ab4688ac43d40aad7ddb955053c6fc3abaf16511a74ef0894214b404c700001c4a4ac02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a010000772a2a0000ff010001000000000e000c0000096c6f63616c686f73740017000000230000000d00140012040308040401050308050501080606010201000500050100000000001200000010000e000c02683208687474702f312e3175500000000b00020100000a000a0008dada001d00170018aaaa00010016030300500200004c0303830fe44c4f3d85e3d95f6b0043de6f87e2e6613625d39fd5fa42d85a34fd558000c02f00002400000000ff01000100000b000403000102002300000010000b000908687474702f312e31160303018a0b0001860001830001803082017c30820126020900f222ec913dca89ff300d06092a864886f70d01010b05003045310b30090603550406130241553113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464301e170d3139313231363133313431305a170d3230303131353133313431305a3045310b30090603550406130241553113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464305c300d06092a864886f70d0101010500034b003048024100bfec7d37cf10f1948ae1cabf9b9c94133530755ed0276a9fe6d52a060d348017189a4e870b607f389ed4044913b9b845c0ad835370344d0b3e174ea8d63f36790203010001300d06092a864886f70d01010b0500034100781581578ce8a601dedb1a0469771843aa47f7a493c4e5e459b978507399faa9b043cbda16c832bc522ea035a47280e991048bfa425b499a58a9057c3ef54740160303008d0c000089030017410433bad3063e435c706c39a994d83f1d69bb30cfd12150d5bb4e16584d1751ce5cdeefaefa57b2f9cced0f9f86b2ced66f0e00ee2c9d21b7a4a77351299c984063040100407703282574ba1e59284b3853ab108f06d2cf072cc9cabf89787fe8a7fad450301fe3c6091126ab4a967f1dcf8d96857ebd7bca27bce1ca5fe08c1316531b58f316030300040e0000001603030046100000424104d2fd09c930874f11669ec3984cdd2efb58723923b9f09dba2542cebe78bcbf5fbdebf9c4f3e09a43717e55c9c8894a44a7ea982372a6412281b078ee72ad2529
14893b9f972337e124d5800a20ef17af838d0656622cb7de6e26951b0fa1cd65
49a52d49768df624fadd438a
~/tls_test/master_key » echo -n "84d061c5ef4bf433f4f897cb2fcf8a53896e8d0ae7d5adc378b0e5c42cfc9abe43513bfe2408b0ab30217fabd6474c7b636c69656e742066696e697368656414893b9f972337e124d5800a20ef17af838d0656622cb7de6e26951b0fa1cd65" | xxd -r -p | sha256sum 4a752a714db4ce8708f018f85f88f6759f3cfd14b9f1e6d1eaea8147f295e39a -