当前位置:首页 > 创新应用 > 正文

HTTPS 温故知新(四)——直观感受 TLS 握手流程(结尾)

这是直观感受TLS握手流程最后一部分。十.直观感受会话恢复这一章,笔者用wireshark抓取会话恢复中的数据包,让读者直观感受一下会话恢复流程。1.PSK会话恢复这是会话恢复的完整流程。上面这4个扩展是会话恢复中ClientHello必须配置的。psk_key_exchange_modes、pre...

这是直观感受TLS握手流程最后一部分。十.直观感受会话恢复这一章,笔者用wireshark抓取会话恢复中的数据包,让读者直观感受一下会话恢复流程。1.PSK会话恢复这是会话恢复的完整流程。上面这4个扩......

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

十.直观感受会话恢复

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

1.PSK会话恢复


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





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




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


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

2.0-RTT

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


GoogleChromeCanary最新74.0.3702.0还不能支持0-RTT模式,FirefoxNightly最新67.0a1可以支持0-RTT模式(在about:config中_0rtt_data设置为true),Safari最新的12.0.3(14606.4.5)还不能支持0-RTT模式。所以笔者只能用FirefoxNightly抓取0-RTT的包。

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

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









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

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

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

$openssls_:443-tls1_3-keylogfile=/Users/ydz/Documents/_out=/Users/ydz/Documents/

输出如下:

CONNECTED(00000006)depth=1C=US,O=Let'sEncrypt,CN=Let'sEncryptAuthorityX3verifyerror:num=20:unabletogetlocalissuercertificate---Certificatechain0s:CN=:C=US,O=Let'sEncrypt,CN=Let'sEncryptAuthorityX31s:C=US,O=Let'sEncrypt,CN=Let'sEncryptAuthorityX3i:O=DigitalSignatureTrustCo.,CN=DSTRootCAX32s:C=US,O=Let'sEncrypt,CN=Let'sEncryptAuthorityX3i:O=DigitalSignatureTrustCo.,CN=DSTRootCAX3---Servercertificate-----BEGINCERTIFICATE-----MIIEljCCA36gAwIBAgISA9VdA6rPN6mIzBxEPL/3iAICMA0GCSqGSIb3DQEBCwUAMEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xOTAyMTAwMTQxMjJaFw0xOTA1MTEwMTQxMjJaMBcxFTATBgNVBAMTDGhhbGZyb3N0LmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABA7sYzIwq29BkT1mQ2TSZRPe34BlnuqN65xoLY+A87M8PpblV0IvNyj4ZdcgiSmSZffocVF6wzck6TmsQ/j2/sujggJyMIICbjAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOD4YIpf+PkD1Jvy+eayPn0csEi/MB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMG8GCCsGAQUFBwEBBGMwYTAuBggrBgEFBQcwAYYiaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9yZzAvBggrBgEFBQcwAoYjaHR0cDovL2NlcnQuaW50LXgzLmxldHNlbmNyeXB0Lm9yZy8wKQYDVR0RBCIwIIIMaGFsZnJv\ghfhjghjjbmd3cuaGFsZnJvc3QuY29tMEwGA1UdIARFMEMwCAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHUA4mlLribo6UAJ6IYbtjuD1D7n/nSI+6SPKJMBnd3x2/4AAAFo1UfZTgAABAMARjBEAiAsXJLCA5uO2R926Dba3fZpV/zvzG9tCPVtTKAeso5bAwIgMXoLRtLqhG5bEcXIpGXJcrd06S8tbUdS9YRAIWpMX1oAdgApPFGWVMg5ZbqqUPxYB9S3b79Yeily3KTDDPTlRUf0eAAAAWjVR9lQAAAEAwBHMEUCIHv6NJ9MWMiL+AHxU8ilL3APMmPkUcc03SjBiDaWVm6JAiEA5YF/XHKuYH0S0+mqfB+YdT0FIey9wFQObkR4/Qvzla4wDQYJKoZIhvcNAQELBQADggEBAHU7a+EgzdhrsyD+2ch7AGD1n1TjDfdxkEjmoitN0Tjh4q3jP/IK7FPs0LBsDRusmtJVK3gZQc9cTEy/om86VQtcnV0LhK83GnFUIuLTEzeTZmnz6Qbs3KznprZH0DRUbfpmZsDNIfBEOUOXiBR4DpLd3tPVfRkQowmO6o39vM4UOGlB0zIAg977q97IT6wS9BCEiGmuF0HSjpLfiPhTy9bpl2VGcJVpIy2TS+d4+JWRI7K5BFSzncGDzHJ+zGsx4wS+dxuiwaS9hw4c0FG2V4kMFnA+orAa/oTnfwFlRIehTbDBO+rNTNtjm4yh63M9gInoQEI1REl2EkGcWug6Ijs=-----ENDCERTIFICATE-----subject=CN==C=US,O=Let'sEncrypt,CN=Let'sEncryptAuthorityX3---NoclientcertificateCAnamessentPeersigningdigest:SHA256Peersignaturetype:ECDSAServerTempKey:X25519,253bits---SSLhandshakehasread3912bytesandwritten316bytesVerificationerror:unabletogetlocalissuercertificate---New,,CipherisTLS_AES_256_GCM_SHA384Serverpublickeyis256bitSecureRenegotiationISNOTsupportedCompression:NONEExpansion:NONENoALPNnegotiatedEarlydatawasnotsentVerifyreturncode:20(unabletogetlocalissuercertificate)------Post-HandshakeNewSessionTicketarrived:SSL-Session:Protocol::TLS_AES_256_GCM_SHA384Session-ID:DECE5063ABC2D1162A5E767C55083FDFFA6A86B64082FE3AD990A213AESession-ID-ctx:ResumptionPSK:EACCC93ACB3DC420DF5027BEC576EE130D11BF546463034C1BB92B54806057E0C9F5C3DB557AD10D425EPSKidentity:NonePSKidentityhint:NoneSRPusername:NoneTLSsessionticketlifetimehint:86400(seconds)TLSsessionticket:0000-0]c!\.0020-6745a3a02865ea9c-c8d4cfdf5dc55abegE..(e]..0040-6{R9am0050-75f8cb43111d58a2-de2b74b0ca70a29cu..C..X..+t..p..0060-856.]0070-5~.-7Ix..xn0080-624b99e737033ea2-89de6148a1c57718bK..7.aH..[.00a0-98dc7e94f8ef4a72-ffbae50307c73dd0..~Jr=.00b0-c891a6ae9adf9225-05637703b0bcb4ab.%.c00c0-36cb0f8c5dec5865-7c972a30574a96b96].Xe|.*0WJ..00d0-60211276774c6d0d-120c50ccf5da544e`!.vwLmPTN00e0-4b275f1bdd11b18d-7fe0374334a38834K'_.7C4..4StartTime:1549886406Timeout:7200(sec)Verifyreturncode:20(unabletogetlocalissuercertificate)Extedmastersecret:noMaxEarlyData:16384---readRBLOCK

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

$openssls_:443-tls1_3-keylogfile=/Users/ydz/Documents/_in=/Users/ydz/Documents/_data=/Users/ydz/Documents/

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

GET/HTTP/1.1HOST::657567765

执行s_client以后,输出如下:

CONNECTED(00000006)---Servercertificate-----BEGINCERTIFICATE-----MIIElzCCA3+gAwIBAgISA604VEs+7Wwch5cNQDshC4t+MA0GCSqGSIb3DQEBCwUAMEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xODEyMDgxMzQzMzhaFw0xOTAzMDgxMzQzMzhaMBcxFTATBgNVBAMTDGhhbGZyb3N0LmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABA7sYzIwq29BkT1mQ2TSZRPe34BlnuqN65xoLY+A87M8PpblV0IvNyj4ZdcgiSmSZffocVF6wzck6TmsQ/j2/sujggJzMIICbzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOD4YIpf+PkD1Jvy+eayPn0csEi/MB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMG8GCCsGAQUFBwEBBGMwYTAuBggrBgEFBQcwAYYiaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9yZzAvBggrBgEFBQcwAoYjaHR0cDovL2NlcnQuaW50LXgzLmxldHNlbmNyeXB0Lm9yZy8wKQYDVR0RBCIwIIIMaGFsZnJvc3QuY29tghB3d3cuaGFsZnJvc3QuY29tMEwGA1UdIARFMEMwCAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHUA4mlLribo73qkwe6lN9vZWu1dJV8+Q41cFLGYMJhDD56x7QIgL+V6g1CQst9UDXobdkAEnjahKiJWihr/Qn3plzgzjiIAdwApPFGWVMg5ZbqqUPxYB9S3b79Yeily3KTDDPTlRUf0eAAAAWeORhq2AAAEAwBIMEYCIQD1Mf1GtmegyTqIu0S3Q4afNDt0srIFyrtROtn0jQAV1gIhAJwXIGyMj87kjHtRc/mHJOOCZRSUvoasvWrytCv2dPwXMA0GCSqGSIb3DQEBCwUAA4IBAQB3sC7jKVGHR8MnAOWnECO/V5Z4oBqbahogwyhOSrbxuutijhyk8kb3A73Q++Ey150Y+hlNUQStmG9JBGg9pyLG2Yug9p5L13a6VrNaL1VQ1Dq6YgS55J8ElsalUgr+9jvTJesdYzfXPdsc8IK67tBXhukqc0/cT3I1QHNwAVru/AKWrkneH4AcadSeLGe5he2X9OV3JJg+gb/vE90UaVmqwUuSGMzluyBXPMuznTa/+7+31vWVQ8aWE32X+E5qHSyeLU808mZHYjvKHvuDnNNu6I0KlNcVJf1s0jOQOjgo7hIP/OR4OlW6ywk07IupV4w07xykP1/tWBsSCviXECcZ-----ENDCERTIFICATE-----subject=CN==C=US,O=Let'sEncrypt,CN=Let'sEncryptAuthorityX3---NoclientcertificateCAnamessentServerTempKey:X25519,253bits---SSLhandshakehasread245bytesandwritten649bytesVerificationerror:unabletogetlocalissuercertificate---Reused,,CipherisTLS_AES_256_GCM_SHA384Serverpublickeyis256bitSecureRenegotiationISNOTsupportedCompression:NONEExpansion:NONENoALPNnegotiatedEarlydatawasacceptedVerifyreturncode:20(unabletogetlocalissuercertificate)---

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


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

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


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


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

十一.的状态机

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

START----+SClientHello||RecvHelloRetryRequest[K_s=earlydata]||v|/WAIT_SH----+||RecvServerHello||K_recv=handshakeCan|Vs|WAIT_EEearly||RecvEncryptedExtensionsdata|+--------+--------+|Using||Usingcertificate|PSK|v||WAIT_CERT_CR||Recv||RecvCertificateRequest||Certificate|v|||WAIT_CERT||||RecvCertificate||vv||WAIT_CV|||RecvCertificateVerify|+WAIT_FINISHED+||RecvFinished\|[SOfEarlyData]|K_s=handshake|[SCertificate[+CertificateVerify]]Cans|SFinishedappdata--|K_s=K_recv=applicationafterherevCONNECTED

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

START-----+RecvClientHello||SHelloRetryRequestv|RECVD_CH----+|SelectparametersvNEGOTIATED|SServerHello|K_s=handshake|SEncryptedExtensions|[SCertificateRequest]Cans|[SCertificate+CertificateVerify]appdata|SFinishedafter--|K_s=applicationhere+--------+--------+No0-RTT||0-RTT||K_recv=handshake||K_recv=earlydata[Skipdecrypterrors]|+------WAIT_EOED-+||Recv||RecvOfEarlyData||earlydata||K_recv=handshake|+------------+|||+WAIT_FLIGHT2--------+|+--------+--------+Noauth||Clientauth|||v|WAIT_CERT|Recv||RecvCertificate|empty|v|Certificate|WAIT_CV|||Recv|v|CertificateVerify+-WAIT_FINISHED---+|RecvFinished|K_recv=applicationvCONNECTED

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

全文完。

Reference:

RFC8466

最新文章