博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tls 1.2 example
阅读量:3964 次
发布时间:2019-05-24

本文共 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.
image.png
image.png

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;

image.png

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;

image.png

Certificate

opaque ASN.1Cert<1..2^24-1>;      struct {          ASN.1Cert certificate\_list<0..2^24-1>;      } Certificate;

image.png

证书内容效验

可以看到,发给客户端挑选的证书,只有前面生成的部分.

抓包内容

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.

image.png

验证

签名验证

签名数据

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 | 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.

image.png

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.

image.png

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的解释:

16030100c0010000bc030340d527ab4688ac43d40aad7ddb955053c6fc3abaf16511a74ef0894214b404c700001c4a4ac02bc02fc02cc030cca9cca8c013c014009c009d002f0035000a010000772a2a0000ff010001000000000e000c0000096c6f63616c686f73740017000000230000000d00140012040308040401050308050501080606010201000500050100000000001200000010000e000c02683208687474702f312e3175500000000b00020100000a000a0008dada001d00170018aaaa00010016030300500200004c0303830fe44c4f3d85e3d95f6b0043de6f87e2e6613625d39fd5fa42d85a34fd558000c02f00002400000000ff01000100000b000403000102002300000010000b000908687474702f312e31160303018a0b0001860001830001803082017c30820126020900f222ec913dca89ff300d06092a864886f70d01010b05003045310b30090603550406130241553113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464301e170d3139313231363133313431305a170d3230303131353133313431305a3045310b30090603550406130241553113301106035504080c0a536f6d652d53746174653121301f060355040a0c18496e7465726e6574205769646769747320507479204c7464305c300d06092a864886f70d0101010500034b003048024100bfec7d37cf10f1948ae1cabf9b9c94133530755ed0276a9fe6d52a060d348017189a4e870b607f389ed4044913b9b845c0ad835370344d0b3e174ea8d63f36790203010001300d06092a864886f70d01010b0500034100781581578ce8a601dedb1a0469771843aa47f7a493c4e5e459b978507399faa9b043cbda16c832bc522ea035a47280e991048bfa425b499a58a9057c3ef54740160303008d0c000089030017410433bad3063e435c706c39a994d83f1d69bb30cfd12150d5bb4e16584d1751ce5cdeefaefa57b2f9cced0f9f86b2ced66f0e00ee2c9d21b7a4a77351299c984063040100407703282574ba1e59284b3853ab108f06d2cf072cc9cabf89787fe8a7fad450301fe3c6091126ab4a967f1dcf8d96857ebd7bca27bce1ca5fe08c1316531b58f316030300040e0000001603030046100000424104d2fd09c930874f11669ec3984cdd2efb58723923b9f09dba2542cebe78bcbf5fbdebf9c4f3e09a43717e55c9c8894a44a7ea982372a6412281b078ee72ad2529

hash 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

转载地址:http://xqzki.baihongyu.com/

你可能感兴趣的文章
Spring - Sentinel 原理 全解析
查看>>
Spring - 比较Sentinel和Hystrix
查看>>
Spring - Nacos 服务注册与发现原理分析
查看>>
Spring - Nacos 配置中心原理分析
查看>>
Spring - Nacos 配置实时更新原理分析
查看>>
Android开发MVP模式(解决了View和Model的耦合)
查看>>
Android网络框架Volley(实战篇)
查看>>
Android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配注意事项
查看>>
Android 5.0学习之感想篇(含Demo)
查看>>
ViewPagerindicator 源码解析
查看>>
HoloGraphLibrary 源码解析
查看>>
CircularFloatingActionMenu 源码解析
查看>>
PhotoView 源码解析
查看>>
Android Lock Pattern 源码解析
查看>>
Java 动态代理
查看>>
Java 注解 Annotation
查看>>
View 绘制流程
查看>>
依赖注入
查看>>
View 事件传递
查看>>
android 各式各样progress 进度条大全
查看>>