Https全揭秘系列 - 抓包的魅力
Posted 框架那些事儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Https全揭秘系列 - 抓包的魅力相关的知识,希望对你有一定的参考价值。
Https全揭秘系列 - 抓包的魅力
上一篇文章由于篇幅限制没有展开抓包相关内容,本篇文章中我将详细的针对抓包进行展开,总结一句话:一切尽在抓包中~
1.抓包篇
1.1抓包之准备工作
抓包工具最常用的就是Wireshark和Fidder,这两种我都用过,仅仅针对抓包的话个人感觉还是Wireshark功能更强大,界面更友好。Wireshark抓包教程网上太多了,这里只简单过一下。
首先,启动wireshark后需要先选择一个接口,由于我们上一篇文章中写的服务端和客户端都是部署在Localhost上的,所以需要专门抓本地流量的接口,这里我推荐使用npcap
像上图中的包过于凌乱,我们需要进行过滤,我们的服务端端口为8083,那么我们设置过滤器为8083,协议为ssl
现在准备工作完成了,开始正式的分析吧
1.2 TLS握手流程
首先启动服务端和客户端,完成一个完整的双向认证流程。
为了区别客户端和服务端发送的包我将客户端发送的包使用深蓝色标记出来了,也就是4、8、10、12、14、20这几个包。下面我将按照顺序一个个解析包中的信息。
1.2.1 Client Hello
首先是客户端发送给服务端的第一个包,我们只看标记出的重要信息
Client Hello指明身份,Version指明客户端使用的TLS握手协议版本(SSL,TLSv1.0,TLSv1.1,TLSv1.2),一般来讲服务端都会支持多种TLS协议版本,当Client Hello包中客户端指明版本后服务端会自动选择匹配的版本进行通信,那么如果服务端不支持客户端使用的TLS版本呢?先卖个关子
接下来,Random Bytes为客户端生成的一个随机数(Random 1),这个Random值将会用在生成加密密钥上。最后,Cipher Suits指明客户端支持的加密套件,服务端将会从这些套件中选择一个作为以后通信的加密算法。
1.2.2 Server Hello, Certificate, Server Key Exchange, Certificate Request, Server Hello Done
这一连串包需要一起讲一下,因为服务端一般都是将这几个握手包合成一个大包发送的。
Server Hello包中有服务端的TLS握手版本,服务端生成的一个随机数(Random 2),会话ID:Https握手会话复用时使用,服务端决定使用的加密套件。
Server Key Exchange这个包比较复杂,里面内容由加密算法决定,客户端和服务端会根据某种算法计算出一个值进行交换,关于这一块想深入了解的可以研究下DHE/ECDHE非对称密钥协商算法。
Certificate Request是服务端要求客户端上传证书(单向认证中没有这个包), Server Hello Done通知客户端Hello过程结束。
1.2.3 Certificate、Client Key Exchange
看完了上面服务端发送的Certificate我们再看客户端Certificate包的就会一目了然,这里不再重复。
客户端在校验通过服务端证书后会取出证书中的公钥,再生成一个随机数(Random 3),使用这个公钥去加密这个随机数生成一个加密数。
至于Client Key Exchange包类似Server Key Exchange包,会发送上面生成的随机数给服务端,服务端可以使用自己的私钥去解密这个加密数获取客户端生成的随机数,到此为止客户端和服务端都拥有了三个随机数,这三个随机数将用于生成最终的加密密钥。
1.2.4 Certificate Verify
这个包比较难解释,我看过网上很多人的解释都不满意,我自己现在也无法给出一个确切描述,这里贴出IETF的解释大家还是看文档定义自行理解吧
This message is used to provide explicit verification of a client
certificate. This message is only sent following a client
certificate that has signing capability (i.e., all certificates
except those containing fixed Diffie-Hellman parameters). When
sent, it MUST immediately follow the client key exchange message.
详细解释可查看RFC5246:https://tools.ietf.org/html/rfc5246#section-7.4.8https://tools.ietf.org/html/rfc5246#section-7.4.8
1.2.5 Change Cipher Verity、Encrypted Handshake Message
Change Cipher Verity包通知服务端开始使用加密密钥进行加密。
Encrypted Handshake Message包是客户端发送的第一条使用加密密钥进行加密的包,里面只包含握手摘要信息。服务端在接受到这个包后会使用同样的密钥解密,如果解密成功取出这个摘要信息那么继续通信,如果无法解密则通信终止。
后面两个服务端发送的相同的包不再解释,同客户端。
最终,在客户端解密服务端发来的握手摘要成功后会发送真正的数据,也就是Application Data这个包,服务端也会发送一条这个包,至此TLS握手过程结束,以后发送的所有数据包都会进行加密。
1.3 JVM信息
通过抓包完成整个流程的理解后,我们还可以再通过设置上一篇文章中提到的JVM参数来打印出握手信息。
下面我将贴出简化版的客户端握手信息,包中看不到的操作可以在这里面查看到。
*** ClientHello, TLSv1.2
*** ServerHello, TLSv1.2
RandomCookie: GMT: 1512931872 bytes = { 236, 91, 72, 220, 191, 86, 188, 238, 250, 83, 108, 218, 58, 51, 129, 225, 49, 223, 150, 209, 56, 198, 79, 15, 85, 52, 5, 55 }
Session ID: {90, 46, 130, 32, 117, 78, 22, 174, 158, 12, 145, 25, 223, 158, 11, 188, 134, 213, 219, 212, 230, 117, 252, 200, 239, 192, 77, 37, 175, 98, 39, 184}
Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
***
%% Initialized: [Session-1, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256]
** TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=127.0.0.1, OU=A, O=B, L=C, ST=D, C=E
Signature Algorithm: SHA1withDSA, OID = 1.2.840.10040.4.3
Validity: [From: Sat Dec 09 17:36:37 CST 2017,
To: Fri Mar 09 17:36:37 CST 2018]
Issuer: CN=127.0.0.1, OU=A, O=B, L=C, ST=D, C=E
SerialNumber: [ 02b2afcf]
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 2E 23 3F E3 D9 F1 D9 84 C0 1C 46 E9 0D 54 51 E2 .#?.......F..TQ.
0010: 97 F3 25 9C ..%.
]
]
]
Algorithm: [SHA1withDSA]
Signature:
0000: 30 2C 02 14 2F 64 42 DD 46 C7 B3 30 7E 1C 98 18 0,../dB.F..0....
0010: 6A F0 1F E7 E2 60 DE 4F 02 14 7B 11 3D 9E 82 6F j....`.O....=..o
0020: 6A CD A0 BE 8C 06 11 23 E0 D3 8A 65 E6 0A j......#...e..
]
***
Found trusted certificate:
[
[
Version: V3
Subject: CN=127.0.0.1, OU=A, O=B, L=C, ST=D, C=E
Signature Algorithm: SHA1withDSA, OID = 1.2.840.10040.4.3
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 2E 23 3F E3 D9 F1 D9 84 C0 1C 46 E9 0D 54 51 E2 .#?.......F..TQ.
0010: 97 F3 25 9C ..%.
]
]
]
Algorithm: [SHA1withDSA]
Signature:
0000: 30 2C 02 14 2F 64 42 DD 46 C7 B3 30 7E 1C 98 18 0,../dB.F..0....
0010: 6A F0 1F E7 E2 60 DE 4F 02 14 7B 11 3D 9E 82 6F j....`.O....=..o
0020: 6A CD A0 BE 8C 06 11 23 E0 D3 8A 65 E6 0A j......#...e..
]
*** Diffie-Hellman ServerKeyExchange
Server DH Public Key: { 151, 242, 249, 64, 196, 1, 60, 179, 167, 31, 78, 168, 117, 55, 247, 249, 207, 27, 39, 74, 193, 5, 146, 94, 72, 12, 78, 47, 5, 170, 247, 129, 7, 3, 199, 224, 109, 164, 146, 4, 128, 189, 219, 195, 162, 151, 26, 241, 127, 233, 27, 142, 206, 59, 4, 23, 147, 244, 136, 81, 83, 72, 192, 182, 47, 87, 169, 138, 121, 190, 7, 248, 143, 130, 190, 207, 225, 253, 206, 250, 198, 82, 48, 174, 191, 154, 251, 14, 5, 151, 169, 117, 25, 136, 68, 72, 208, 8, 193, 59, 233, 54, 144, 99, 77, 138, 76, 172, 207, 161, 205, 134, 25, 27, 0, 45, 239, 57, 81, 251, 132, 195, 144, 124, 88, 202, 51, 224 }
Anonymous
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Cert Authorities:
<CN=127.0.0.1, OU=1, O=2, L=3, ST=4, C=5>
*** ServerHelloDone
matching alias: client
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=127.0.0.1, OU=1, O=2, L=3, ST=4, C=5
Signature Algorithm: SHA1withDSA, OID = 1.2.840.10040.4.3
Validity: [From: Sat Dec 09 18:01:04 CST 2017,
To: Fri Mar 09 18:01:04 CST 2018]
Issuer: CN=127.0.0.1, OU=1, O=2, L=3, ST=4, C=5
SerialNumber: [ 225ee3b3]
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 10 CE 04 49 99 F1 CA A6 C3 94 B9 69 C1 2C 64 3C ...I.......i.,d<
0010: D0 BC F3 CC ....
]
]
]
Algorithm: [SHA1withDSA]
Signature:
0000: 30 2D 02 14 03 92 35 EF EC 41 5E 7B C1 3A 15 E7 0-....5..A^..:..
0010: F2 5E 98 B8 88 FB 5B 1B 02 15 00 83 CC 6B 47 CA .^....[......kG.
0020: 79 06 1D 04 5E 35 09 4A 3A E4 70 56 FD 29 F5 y...^5.J:.pV.).
]
***
*** ClientKeyExchange, DH
DH Public key: { 179, 59, 152, 150, 251, 37, 68, 106, 188, 231, 147, 127, 22, 22, 62, 71, 37, 76, 110, 131, 29, 96, 137, 161, 165, 176, 219, 158, 82, 237, 130, 114, 40, 90, 11, 225, 6, 169, 4, 107, 6, 186, 113, 19, 152, 179, 16, 74, 72, 1, 16, 135, 148, 174, 1, 128, 49, 241, 163, 151, 68, 9, 26, 150, 234, 85, 59, 154, 129, 140, 239, 74, 163, 6, 117, 181, 249, 181, 150, 183, 7, 137, 116, 250, 17, 30, 131, 158, 71, 14, 178, 88, 235, 5, 87, 171, 221, 0, 134, 147, 118, 132, 122, 38, 183, 47, 201, 229, 227, 162, 243, 251, 18, 13, 113, 131, 124, 177, 254, 26, 80, 22, 110, 45, 151, 65, 131, 203 }
SESSION KEYGEN:
PreMaster Secret:
0000: 88 AD 4B 9E 08 CA 85 F7 A3 62 38 58 EF 6C 3A 3E ..K......b8X.l:>
0010: DB BC 72 4D B7 CC CC C3 20 5E A2 50 7D 01 0C 4A ..rM.... ^.P...J
0020: 26 C3 C0 37 0B 25 D5 AF FC 8D 94 00 FA B5 F7 76 &..7.%.........v
0030: E3 5C 62 B4 06 62 FB AD 30 6C EE 4F D7 7B FC DE .\b..b..0l.O....
0040: 68 A2 AB CF 14 00 B2 43 C1 B3 5D 98 FC 7B 62 84 h......C..]...b.
0050: D3 8A 27 90 A7 5F CC D2 62 53 9E 1B 16 B3 FB 34 ..'.._..bS.....4
0060: 1A B5 7F 9E 0C 7C 10 51 69 34 82 BB 71 DB 2D 9A .......Qi4..q.-.
0070: 23 3E 16 CB 88 44 4E 1E FB 9F FC 3D 0F 4F 03 5F #>...DN....=.O._
*** CertificateVerify
Signature Algorithm SHA256withDSA
main, WRITE: TLSv1.2 Handshake, length = 54
main, WRITE: TLSv1.2 Change Cipher Spec, length = 1
*** Finished
verify_data: { 250, 250, 27, 237, 186, 157, 102, 93, 223, 61, 94, 120 }
***
*** Finished
verify_data: { 188, 129, 85, 66, 73, 192, 173, 13, 60, 209, 92, 250 }
***
%% Cached client session: [Session-1, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256]
上面的控制台信息大家结合抓包流程中的包进行对应理解,这里不再一条条展开讲解,想要理解这种网络协议,一定要自己实际操作,上一篇文章中我给出了源码,即使对Jetty、Servlet、HttpClient不理解也可以直接运行服务端和客户端进行调试Https相关内容或者抓包,希望我的文章对各位有所帮助。
本篇文章我们结合了抓包与JVM握手信息讲解了这个握手过程,下一篇文章中我将针对各种Https握手失败情景进行详细分析,其中将分享一个貌似目前没有人发现的一个JDK的BUG。
如果您觉得我的文章对您有帮助,请点个赞或者转发此文章,感谢您的支持!
以上是关于Https全揭秘系列 - 抓包的魅力的主要内容,如果未能解决你的问题,请参考以下文章