本文共 16491 字,大约阅读时间需要 54 分钟。
前言
这篇blog类似Example Handshake Traces for TLS 1.3. 人肉trace/verify一个典型的TLS 1.2握手.
因为hash值无法反推, 理解错误时很难debug. 读rfc文档的效率不如直接阅读代码. Finished消息之后的内容尚未验证完毕.准备工作
nginx
# 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 生成证书
生成私钥和签名请求
openssl提示, private key至少是512 bits.
ubuntu# openssl req -new -newkey rsa:512 -nodes -keyout server.key -out server.csr
私钥内容
私钥内容会用于下面的计算.
ubuntu# openssl rsa -text -in server.keyPrivate-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:79publicExponent: 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:6dprime1: 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:1bprime2: 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:fbexponent1: 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:a5exponent2: 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:3bcoefficient: 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:41writing RSA key-----BEGIN RSA PRIVATE KEY-----MIIBOgIBAAJBAL/sfTfPEPGUiuHKv5uclBM1MHVe0Cdqn+bVKgYNNIAXGJpOhwtgfzie1ARJE7m4RcCtg1NwNE0LPhdOqNY/NnkCAwEAAQJAMPkUfrAsv6hKxBDrUbbjpf8VjW2TKeuwP8O3BHJMKj7JXaOu+yewe3S0CCYnxvA0JNghMp/+wZBFiwqAZ7R3bQIhAN7RUEK6iotkR3rpgwKn4I07hFZhzhp9SG6tl02Fx74bAiEA3IFhZMWQ9rSHHh/G0WLLA3/QZv8d6H6/zuM/cLZMlvsCIDRPe8JOvRwAjO+ERuemtgcyQ91r1NFPPGQPiQgAMmalAiEAxO0jLt0mfr1xIl0csWj6h9CBLUrPyhBQepMG2EFmmzsCIEekEAPQs4NiM5W+XOsrTFuH1IlPXfgVokx9Wlg7AJ9B-----END RSA PRIVATE KEY-----
生成证书
ubuntu# openssl x509 -req -in server.csr -signkey server.key -out server.crtSignature oksubject=/C=AU/ST=Some-State/O=Internet Widgits Pty LtdGetting Private key
ssl key log
只有用RSA作为密钥加密算法时, 才能仅依据RSA私钥解密整个通信内容. 所以要记录ssl握手日志.
握手日志格式:Key_Log_Format在bashrc里export的方式对我无效. 于是直接在启动命令行上export.key log
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
ClientHello
该步骤完全是明文.
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;
ServerHello
该步骤完全是明文
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;
Certificate
opaque ASN.1Cert<1..2^24-1>; struct { ASN.1Cert certificate\_list<0..2^24-1>; } Certificate;
证书内容效验
可以看到,发给客户端挑选的证书,只有前面生成的部分.
抓包内容
copy as a Hex Stream
3082017c30820126020900f222ec913dca89ff300d06092a864886f70d01010b05003045310b30090603550406130241553113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464301e170d3139313231363133313431305a170d3230303131353133313431305a3045310b30090603550406130241553113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464305c300d06092a864886f70d0101010500034b003048024100bfec7d37cf10f1948ae1cabf9b9c94133530755ed0276a9fe6d52a060d348017189a4e870b607f389ed4044913b9b845c0ad835370344d0b3e174ea8d63f36790203010001300d06092a864886f70d01010b0500034100781581578ce8a601dedb1a0469771843aa47f7a493c4e5e459b978507399faa9b043cbda16c832bc522ea035a47280e991048bfa425b499a58a9057c3ef54740
证书内容
~/tls_test » cat server.crt | grep -v "CERTIFICATE" | base64 -d | xxd00000000: 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....A00000030: 5531 1330 1106 0355 0408 0c0a 536f 6d65 U1.0...U....Some00000040: 2d53 7461 7465 3121 301f 0603 5504 0a0c -State1!0...U...00000050: 1849 6e74 6572 6e65 7420 5769 6467 6974 .Internet Widgit00000060: 7320 5074 7920 4c74 6430 1e17 0d31 3931 s Pty Ltd0...19100000070: 3231 3631 3331 3431 305a 170d 3230 3031 216131410Z..200100000080: 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!0000000b0: 1f06 0355 040a 0c18 496e 7465 726e 6574 ...U....Internet000000c0: 2057 6964 6769 7473 2050 7479 204c 7464 Widgits Pty Ltd000000d0: 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^.'j00000100: 9fe6 d52a 060d 3480 1718 9a4e 870b 607f ...*..4....N..`.00000110: 389e d404 4913 b9b8 45c0 ad83 5370 344d 8...I...E...Sp4M00000120: 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.C00000150: 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@
Server Key Exchange Message
实际使用的算法是dhe_rsa, 参照ServerHello中的Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.
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:
40d527ab4688ac43d40aad7ddb955053c6fc3abaf16511a74ef0894214b404c7server_random:830fe44c4f3d85e3d95f6b0043de6f87e2e6613625d39fd5fa42d85a34fd5580server dh params:030017410433bad3063e435c706c39a994d83f1d69bb30cfd12150d5bb4e16584d1751ce5cdeefaefa57b2f9cced0f9f86b2ced66f0e00ee2c9d21b7a4a77351299c984063all 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 | xxd00000000: 40d5 27ab 4688 ac43 d40a ad7d db95 5053 @.'.F..C...}..PS00000010: 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.X00000060: 4d17 51ce 5cde efae fa57 b2f9 cced 0f9f M.Q.\....W......00000070: 86b2 ced6 6f0e 00ee 2c9d 21b7 a4a7 7351 ....o...,.!...sQ00000080: 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.....P000000020: 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 | xxd00000000: 3031 300d 0609 6086 4801 6503 0402 0105 010...`.H.e.....00000010: 0004 2029 35e7 0121 926d 2e13 d655 9943 .. )5..!.m...U.C00000020: 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 | xxd00000000: 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 ttfc4b5fd6816f75a7c81fc8eaa9499d6a299bd803397166e8c4cf9280b801d62c tt
Server Hello Done
告诉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.
Client Key Exchange
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.
Change Cipher Spec
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
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];
master_secret:
84d061c5ef4bf433f4f897cb2fcf8a53896e8d0ae7d5adc378b0e5c42cfc9abe43513bfe2408b0ab30217fabd6474c7b
finished_label:
~/tls_test/master_key » echo -n "client finished" | xxd -p636c69656e742066696e6973686564
handshake_messages:
如下hex string包含图中的Client Hello, Server Hello, Certificate Server key Exchange, Server Hello Done, Client Key Exchange, 具体看rfc文档对handshake_messages的解释:
16030100c0010000bc030340d527ab4688ac43d40aad7ddb955053c6fc3abaf16511a74ef0894214b404c700001c4a4ac02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a010000772a2a0000ff010001000000000e000c0000096c6f63616c686f73740017000000230000000d00140012040308040401050308050501080606010201000500050100000000001200000010000e000c02683208687474702f312e3175500000000b00020100000a000a0008dada001d00170018aaaa00010016030300500200004c0303830fe44c4f3d85e3d95f6b0043de6f87e2e6613625d39fd5fa42d85a34fd558000c02f00002400000000ff01000100000b000403000102002300000010000b000908687474702f312e31160303018a0b0001860001830001803082017c30820126020900f222ec913dca89ff300d06092a864886f70d01010b05003045310b30090603550406130241553113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464301e170d3139313231363133313431305a170d3230303131353133313431305a3045310b30090603550406130241553113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464305c300d06092a864886f70d0101010500034b003048024100bfec7d37cf10f1948ae1cabf9b9c94133530755ed0276a9fe6d52a060d348017189a4e870b607f389ed4044913b9b845c0ad835370344d0b3e174ea8d63f36790203010001300d06092a864886f70d01010b0500034100781581578ce8a601dedb1a0469771843aa47f7a493c4e5e459b978507399faa9b043cbda16c832bc522ea035a47280e991048bfa425b499a58a9057c3ef54740160303008d0c000089030017410433bad3063e435c706c39a994d83f1d69bb30cfd12150d5bb4e16584d1751ce5cdeefaefa57b2f9cced0f9f86b2ced66f0e00ee2c9d21b7a4a77351299c984063040100407703282574ba1e59284b3853ab108f06d2cf072cc9cabf89787fe8a7fad450301fe3c6091126ab4a967f1dcf8d96857ebd7bca27bce1ca5fe08c1316531b58f316030300040e0000001603030046100000424104d2fd09c930874f11669ec3984cdd2efb58723923b9f09dba2542cebe78bcbf5fbdebf9c4f3e09a43717e55c9c8894a44a7ea982372a6412281b078ee72ad2529hash of handshake_messages:
14893b9f972337e124d5800a20ef17af838d0656622cb7de6e26951b0fa1cd65
verify_data
49a52d49768df624fadd438a
calc verify_data
~/tls_test/master_key » echo -n "84d061c5ef4bf433f4f897cb2fcf8a53896e8d0ae7d5adc378b0e5c42cfc9abe43513bfe2408b0ab30217fabd6474c7b636c69656e742066696e697368656414893b9f972337e124d5800a20ef17af838d0656622cb7de6e26951b0fa1cd65" | xxd -r -p | sha256sum4a752a714db4ce8708f018f85f88f6759f3cfd14b9f1e6d1eaea8147f295e39a -
decrypt
AES-GCM Authenticated Encryption
转载地址:https://blog.csdn.net/qq_45533841/article/details/104269121 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!