tls为什么要分为两层协议(HTTPS温故知新四)

Go语言中文网,致力于每日分享编码、开源等知识,欢迎关注我,会有意想不到的收获!

这是 直观感受 TLS 握手流程 最后一部分。

十. 直观感受 TLS 1.3 会话恢复

这一章,笔者用 wireshark 抓取 TLS 1.3 会话恢复中的数据包,让读者直观感受一下 TLS 1.3 会话恢复流程。

1. PSK 会话恢复

tls为什么要分为两层协议(HTTPS温故知新四)(1)

这是 TLS 1.3 会话恢复的完整流程。

tls为什么要分为两层协议(HTTPS温故知新四)(2)

tls为什么要分为两层协议(HTTPS温故知新四)(3)

tls为什么要分为两层协议(HTTPS温故知新四)(4)

tls为什么要分为两层协议(HTTPS温故知新四)(5)

上面这 4 个扩展是 TLS 1.3 PSK 会话恢复中 ClientHello 必须配置的。psk_key_exchange_modes、pre_shared_key、key_share、supported_versions。

tls为什么要分为两层协议(HTTPS温故知新四)(6)

tls为什么要分为两层协议(HTTPS温故知新四)(7)

tls为什么要分为两层协议(HTTPS温故知新四)(8)

上面这 3 个扩展是 TLS 1.3 PSK 会话恢复中 ServerHello 必须配置的。pre_shared_key、key_share、supported_versions。

tls为什么要分为两层协议(HTTPS温故知新四)(9)

一旦 PSK 校验完成,Server 就不需要再次发送证书了,直接回应 ChangeCipherSpec、Encrypted Extensions、Finished 即可完成会话恢复。

2. 0-RTT

截止到笔者写这篇文章为止,当前主流浏览器对 TLS 1.3 的支持度如下图。

tls为什么要分为两层协议(HTTPS温故知新四)(10)

Google Chrome Canary 最新 74.0.3702.0 还不能支持 0-RTT 模式,Firefox Nightly 最新 67.0a1 可以支持 0-RTT 模式(在 about:config 中 security.tls.enable_0rtt_data 设置为 true),Safari 最新的 12.0.3 (14606.4.5) 还不能支持 0-RTT 模式。所以笔者只能用 Firefox Nightly 抓取 0-RTT 的包。

当然 OpenSSL 最新版 1.1.1a 的 Client 是支持发送 early_data 的,也就是支持 0-RTT 的,用它来调试 TLS 1.3 0-RTT 也更加方便。

先来看看支持 0-RTT 的 Firefox Nightly 抓到的包是怎么样的。

tls为什么要分为两层协议(HTTPS温故知新四)(11)

tls为什么要分为两层协议(HTTPS温故知新四)(12)

tls为什么要分为两层协议(HTTPS温故知新四)(13)

tls为什么要分为两层协议(HTTPS温故知新四)(14)

tls为什么要分为两层协议(HTTPS温故知新四)(15)

tls为什么要分为两层协议(HTTPS温故知新四)(16)

tls为什么要分为两层协议(HTTPS温故知新四)(17)

tls为什么要分为两层协议(HTTPS温故知新四)(18)

可以发现整个会话恢复过程满足了 0-RTT 的条件,所以 0-RTT 开启成功。

在用 OpenSSL 的 Client 来测试测试 0-RTT。

先将必要参数导出来,比如协商的密钥和 session 信息。

$ openssl s_client -connect halfrost.com:443 -tls1_3 -keylogfile=/Users/ydz/Documents/sslkeylog.log -sess_out=/Users/ydz/Documents/tls13.sess

输出如下:

CONNECTED(00000006) depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 verify error:num=20:unable to get local issuer certificate --- Certificate chain 0 s:CN = halfrost.com i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 i:O = Digital Signature Trust Co., CN = DST Root CA X3 2 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 i:O = Digital Signature Trust Co., CN = DST Root CA X3 --- Server certificate -----BEGIN CERTIFICATE----- MIIEljCCA36gAwIBAgISA9VdA6rPN6mIzBxEPL/3iAICMA0GCSqGSIb3DQEBCwUA MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xOTAyMTAwMTQxMjJaFw0x OTA1MTEwMTQxMjJaMBcxFTATBgNVBAMTDGhhbGZyb3N0LmNvbTBZMBMGByqGSM49 AgEGCCqGSM49AwEHA0IABA7sYzIwq29BkT1mQ2TSZRPe34BlnuqN65xoLY A87M8 PpblV0IvNyj4ZdcgiSmSZffocVF6wzck6TmsQ/j2/sujggJyMIICbjAOBgNVHQ8B Af8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB /wQCMAAwHQYDVR0OBBYEFOD4YIpf PkD1Jvy eayPn0csEi/MB8GA1UdIwQYMBaA FKhKamMEfd265tE5t6ZFZe/zqOyhMG8GCCsGAQUFBwEBBGMwYTAuBggrBgEFBQcw AYYiaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9yZzAvBggrBgEFBQcw AoYjaHR0cDovL2NlcnQuaW50LXgzLmxldHNlbmNyeXB0Lm9yZy8wKQYDVR0RBCIw IIIMaGFsZnJv\ghfhjghjjbmd3cuaGFsZnJvc3QuY29tMEwGA1UdIARFMEMwCAYG Z4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMu bGV0c2VuY3J5cHQub3JnMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHUA4mlLribo 6UAJ6IYbtjuD1D7n/nSI 6SPKJMBnd3x2/4AAAFo1UfZTgAABAMARjBEAiAsXJLC A5uO2R926Dba3fZpV/zvzG9tCPVtTKAeso5bAwIgMXoLRtLqhG5bEcXIpGXJcrd0 6S8tbUdS9YRAIWpMX1oAdgApPFGWVMg5ZbqqUPxYB9S3b79Yeily3KTDDPTlRUf0 eAAAAWjVR9lQAAAEAwBHMEUCIHv6NJ9MWMiL AHxU8ilL3APMmPkUcc03SjBiDaW Vm6JAiEA5YF/XHKuYH0S0 mqfB YdT0FIey9wFQObkR4/Qvzla4wDQYJKoZIhvcN AQELBQADggEBAHU7a EgzdhrsyD 2ch7AGD1n1TjDfdxkEjmoitN0Tjh4q3jP/IK 7FPs0LBsDRusmtJVK3gZQc9cTEy/om86VQtcnV0LhK83GnFUIuLTEzeTZmnz6Qbs 3KznprZH0DRUbfpmZsDNIfBEOUOXiBR4DpLd3tPVfRkQowmO6o39vM4UOGlB0zIA g977q97IT6wS9BCEiGmuF0HSjpLfiPhTy9bpl2VGcJVpIy2TS d4 JWRI7K5BFSz ncGDzHJ zGsx4wS dxuiwaS9hw4c0FG2V4kMFnA orAa/oTnfwFlRIehTbDBO rN TNtjm4yh63M9gInoQEI1REl2EkGcWug6Ijs= -----END CERTIFICATE----- subject=CN = halfrost.com issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 --- No client certificate CA names sent Peer signing digest: SHA256 Peer signature type: ECDSA Server Temp Key: X25519, 253 bits --- SSL handshake has read 3912 bytes and written 316 bytes Verification error: unable to get local issuer certificate --- New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 Server public key is 256 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 20 (unable to get local issuer certificate) --- --- Post-Handshake New Session Ticket arrived: SSL-Session: Protocol : TLSv1.3 Cipher : TLS_AES_256_GCM_SHA384 Session-ID: DECE5063ABC2D1162A5E767C55083FDFFA6A86B64082FE3AD990A213AE Session-ID-ctx: Resumption PSK: EACCC93ACB3DC420DF5027BEC576EE130D11BF546463034C1BB92B54806057E0C9F5C3DB557AD10D425E PSK identity: None PSK identity hint: None SRP username: None TLS session ticket lifetime hint: 86400 (seconds) TLS session ticket: 0000 - 0b 8d e5 44 b2 62 71 9d-f9 0a ec da f0 d0 6a 0b ...D.bq.......j. 0010 - 97 5d 63 21 ea 1e 8a 69-01 52 a9 0a 19 bf 5c a3 .]c!...i.R....\. 0020 - 67 45 a3 a0 28 65 ea 9c-c8 d4 cf df 5d c5 5a be gE..(e......].Z. 0030 - 32 45 0d 1e af f7 32 67-4a d8 66 cb b6 cb c8 0e 2E....QgJ.f..... 0040 - 6b b8 53 a8 d2 d4 4b 7b-cc a6 cb 52 39 61 20 6d k.S...K{...R9a m 0050 - 75 f8 cb 43 11 1d 58 a2-de 2b 74 b0 ca 70 a2 9c u..C..X.. t..p.. 0060 - 85 6b 1a 00 9a f1 bd 9b-8c b4 5a 41 aa 4b 64 5d .k........ZA.Kd] 0070 - 5a 48 23 a6 10 49 4f 61-c9 57 74 f4 56 50 83 1a ZH#..IOa.Wt.VP.. 0080 - 1b 74 6c ea 09 99 42 f5-d6 3c 6d 4f 5b 98 ca b3 .tl...B..<mO.... 0090 - c7 72 56 5c 6c 67 71 77-8d 68 f7 54 e5 e3 7b d3 .rV\lgqw.h.T..{. 00a0 - 24 ff 42 0c 3f 12 27 42-7f 9e 0a 4c c2 79 60 45 $.B.?.'B...L.y`E 00b0 - 2d 77 a2 c8 2f f5 85 34-fa ce 79 ee 0b ea 00 c1 -w../..4..y..... 00c0 - 74 33 f0 6c af 7a 1a 55-f8 35 bd 5e 49 66 6f 06 t3.l.z.U.5.^Ifo. 00d0 - c6 38 ed a6 82 e2 c8 77-99 b7 34 9a 4a 9a 31 40 .8.....w..4.J.1@ 00e0 - f1 93 a0 94 7f 1e 8d e0-54 29 dc e3 6f 5c 93 21 ........T)..o\.! Start Time: 1549886406 Timeout : 7200 (sec) Verify return code: 20 (unable to get local issuer certificate) Extended master secret: no Max Early Data: 16384 --- read R BLOCK --- Post-Handshake New Session Ticket arrived: SSL-Session: Protocol : TLSv1.3 Cipher : TLS_AES_256_GCM_SHA384 Session-ID: B7E28DE5DF2C95F2E3DE43732E4F9A45A8943ED3856B73CAB5E7260E7 Session-ID-ctx: Resumption PSK: BF2BA2304BEB2B948F7BF6617D0KDRNFB9CD5466DEC1EB9697D2543B7BB913BC7854359D7F5DF7559D67 PSK identity: None PSK identity hint: None SRP username: None TLS session ticket lifetime hint: 86400 (seconds) TLS session ticket: 0000 - 0b 8d e5 44 b2 62 71 9d-f9 0a ec da f0 d0 6a 0b ...D.bq.......j. 0010 - b4 9f cc 17 63 9a 70 c8-63 f8 2e c4 9f d4 a1 f8 ....c.p.c....... 0020 - 22 34 22 03 d0 f9 78 66-a0 d4 2f 62 53 d3 d8 e3 "4"...xf../bS... 0030 - 55 2c a5 7c 0b 19 b3 fc-77 55 8c de 0b 2d 00 bd U,.|....wUL..-.. 0040 - b8 fa 2e 00 30 78 c8 dc-35 14 d3 61 f0 69 38 59 ...%0x..5..a.i8Y 0050 - ee 2a 75 7e 50 34 3f e3-25 04 71 1c 6e c9 c8 20 .*u~P4?.%.q.n.. 0060 - d7 4e 44 b3 69 56 50 23-38 c2 f1 1e ac 10 a7 ff .ND.iVP#8....... 0070 - 96 cf fe ff 4d 07 7e 08-2d 37 49 78 ab 1d 78 6e ....M.~.-7Ix..xn 0080 - 62 4b 99 e7 37 03 3e a2-89 de 61 48 a1 c5 77 18 bK..7.>...aH..w. 0090 - 6f 1c 95 8a 0d 1d 17 68-88 8a 01 5b f0 dc ea 06 o......h...[.... 00a0 - 98 dc 7e 94 f8 ef 4a 72-ff ba e5 03 07 c7 3d d0 ..~...Jr......=. 00b0 - c8 91 a6 ae 9a df 92 25-05 63 77 03 b0 bc b4 ab .......%.c...... 00c0 - 36 cb 0f 8c 5d ec 58 65-7c 97 2a 30 57 4a 96 b9 6...].Xe|.*0WJ.. 00d0 - 60 21 12 76 77 4c 6d 0d-12 0c 50 cc f5 da 54 4e `!.vwLm...P...TN 00e0 - 4b 27 5f 1b dd 11 b1 8d-7f e0 37 43 34 a3 88 34 K'_.......7C4..4 Start Time: 1549886406 Timeout : 7200 (sec) Verify return code: 20 (unable to get local issuer certificate) Extended master secret: no Max Early Data: 16384 --- read R BLOCK

接下来在复用刚刚的连接,命令如下:

$ openssl s_client -connect halfrost.com:443 -tls1_3 -keylogfile=/Users/ydz/Documents/sslkeylog.log -sess_in=/Users/ydz/Documents/tls13.sess -early_data=/Users/ydz/Documents/req.txt

req.txt 里面只是简单的写一个 GET 请求:

GET / HTTP/1.1 HOST: halfrost.com Early-Data: 657567765

执行 s_client 以后,输出如下:

CONNECTED(00000006) --- Server certificate -----BEGIN CERTIFICATE----- MIIElzCCA3 gAwIBAgISA604VEs 7Wwch5cNQDshC4t MA0GCSqGSIb3DQEBCwUA MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xODEyMDgxMzQzMzhaFw0x OTAzMDgxMzQzMzhaMBcxFTATBgNVBAMTDGhhbGZyb3N0LmNvbTBZMBMGByqGSM49 AgEGCCqGSM49AwEHA0IABA7sYzIwq29BkT1mQ2TSZRPe34BlnuqN65xoLY A87M8 PpblV0IvNyj4ZdcgiSmSZffocVF6wzck6TmsQ/j2/sujggJzMIICbzAOBgNVHQ8B Af8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB /wQCMAAwHQYDVR0OBBYEFOD4YIpf PkD1Jvy eayPn0csEi/MB8GA1UdIwQYMBaA FKhKamMEfd265tE5t6ZFZe/zqOyhMG8GCCsGAQUFBwEBBGMwYTAuBggrBgEFBQcw AYYiaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9yZzAvBggrBgEFBQcw AoYjaHR0cDovL2NlcnQuaW50LXgzLmxldHNlbmNyeXB0Lm9yZy8wKQYDVR0RBCIw IIIMaGFsZnJvc3QuY29tghB3d3cuaGFsZnJvc3QuY29tMEwGA1UdIARFMEMwCAYG Z4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMu bGV0c2VuY3J5cHQub3JnMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHUA4mlLribo 73qkwe6lN9vZWu1dJV8 Q41cFLGYMJhDD56x7QIgL V6g1CQst9UDXobdkAEnjah KiJWihr/Qn3plzgzjiIAdwApPFGWVMg5ZbqqUPxYB9S3b79Yeily3KTDDPTlRUf0 eAAAAWeORhq2AAAEAwBIMEYCIQD1Mf1GtmegyTqIu0S3Q4afNDt0srIFyrtROtn0 jQAV1gIhAJwXIGyMj87kjHtRc/mHJOOCZRSUvoasvWrytCv2dPwXMA0GCSqGSIb3 DQEBCwUAA4IBAQB3sC7jKVGHR8MnAOWnECO/V5Z4oBqbahogwyhOSrbxuutijhyk 8kb3A73Q Ey150Y hlNUQStmG9JBGg9pyLG2Yug9p5L13a6VrNaL1VQ1Dq6YgS5 5J8ElsalUgr 9jvTJesdYzfXPdsc8IK67tBXhukqc0/cT3I1QHNwAVru/AKWrkne H4AcadSeLGe5he2X9OV3JJg gb/vE90UaVmqwUuSGMzluyBXPMuznTa/ 7 31vWV Q8aWE32X E5qHSyeLU808mZHYjvKHvuDnNNu6I0KlNcVJf1s0jOQOjgo7hIP/OR4 OlW6ywk07IupV4w07xykP1/tWBsSCviXECcZ -----END CERTIFICATE----- subject=CN = halfrost.com issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 --- No client certificate CA names sent Server Temp Key: X25519, 253 bits --- SSL handshake has read 245 bytes and written 649 bytes Verification error: unable to get local issuer certificate --- Reused, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 Server public key is 256 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was accepted Verify return code: 20 (unable to get local issuer certificate) ---

从输出中可以看到 Early data was accepted。这个时候转到 wireshark,看抓到的包是怎么样的。

tls为什么要分为两层协议(HTTPS温故知新四)(19)

可以看到 Client 在 ClientHello 之后,就立即发送了 Application Data。

在 wireshark 中首选项,把下图中的勾去掉。

tls为什么要分为两层协议(HTTPS温故知新四)(20)

配置生效以后,可以看到 Application Data 里面的请求了。

tls为什么要分为两层协议(HTTPS温故知新四)(21)

普通的 GET 请求中 header 中带了 Early-Data 的值。这个值就会传给 Server 处理了。

十一. TLS 1.3 的状态机

TLS 1.3 相对 TLS 1.2 握手流程发生了巨大的变化,所以状态机也发生了巨大的变化。下面放 2 张状态流转图,最为总结,对应的也是本篇文章的精华。

START <---- Send ClientHello | | Recv HelloRetryRequest [K_send = early data] | | v | / WAIT_SH ---- | | Recv ServerHello | | K_recv = handshake Can | V send | WAIT_EE early | | Recv EncryptedExtensions data | -------- -------- | Using | | Using certificate | PSK | v | | WAIT_CERT_CR | | Recv | | Recv CertificateRequest | | Certificate | v | | | WAIT_CERT | | | | Recv Certificate | | v v | | WAIT_CV | | | Recv CertificateVerify | > WAIT_FINISHED < | | Recv Finished \ | [Send EndOfEarlyData] | K_send = handshake | [Send Certificate [ CertificateVerify]] Can send | Send Finished app data --> | K_send = K_recv = application after here v CONNECTED

这图是 Client 在握手流程上的状态机。如果读者还不清楚中间的某个步骤,可以对照上文中的内容查缺补漏。

START <----- Recv ClientHello | | Send HelloRetryRequest v | RECVD_CH ---- | Select parameters v NEGOTIATED | Send ServerHello | K_send = handshake | Send EncryptedExtensions | [Send CertificateRequest] Can send | [Send Certificate CertificateVerify] app data | Send Finished after --> | K_send = application here -------- -------- No 0-RTT | | 0-RTT | | K_recv = handshake | | K_recv = early data [Skip decrypt errors] | ------> WAIT_EOED - | | Recv | | Recv EndOfEarlyData | | early data | | K_recv = handshake | ------------ | | | > WAIT_FLIGHT2 <-------- | -------- -------- No auth | | Client auth | | | v | WAIT_CERT | Recv | | Recv Certificate | empty | v | Certificate | WAIT_CV | | | Recv | v | CertificateVerify -> WAIT_FINISHED <--- | Recv Finished | K_recv = application v CONNECTED

这图是 Server 在握手流程上的状态机。如果读者还不清楚中间的某个步骤,可以对照上文中的内容查缺补漏。读者能理解透上面这 2 张状态机,TLS 1.3 也就掌握透彻了。

全文完。


  • Reference:
  • RFC 8466
  • TLS1.3 draft-28

GitHub Repo:Halfrost-Field

Follow: halfrost · GitHub

Source: https://halfrost.com/HTTPS_handshake/

本文作者:于德志 (@halfrost),原创授权发布

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页