在上一篇博客中,我用JAVA编写了一个服务器和客户端程序,实现SSL的双向认证和连接。下面我们可以对整个连接的过程进行抓包分析,更好的理解整个连接的过程,也方便做故障排查。
首先安装wireshark,这是一个很方便的抓包分析工具。启动wireshark, 选择要抓包的网络接口。因为我是在本地运行服务器和客户端程序,因此这里选择loopback接口。之后,我们需要配置一下SSL的端口,因为服务器是设置了9999这个端口来进行连接,这不是默认的SSL端口(443),因此需要在wireshark中配置一下,不然抓到的包里面是没有SSL协议的。
打开wireshark->edit->prefrence->protocols->HTTP,在SSL/TLS ports里面填入443,9999。这样就能抓到SSL协议的包了
在SSL连接建立之后,服务器和客户端的通讯的内容是被加密的,如果我们想要看到这些内容,就需要解密。这里我们需要借助一个第三方的工具,来记录SSL连接建立时协商的随机数和Secret key。我选择的是jSSLKeyLog,下载了这个jar包之后,启动客户端时输入如下命令,就可以把相关的连接信息记录到ssl_logfile.log文件。
java -javaagent:jSSLKeyLog.jar=ssl_logfile.log -jar client-1.0-SNAPSHOT.jar
在wireshark的edit->prefrence->protocols->tls中,(Pre)-Master-Secret log filename输入ssl_logfile.log文件的路径,wireshark就能帮我们解密SSL传输的application data的信息。
以下是我在wireshark中抓取的SSL双向认证连接的数据包:
No. Time Source Destination Protocol Length Info
1 0.000000 127.0.0.1 127.0.0.1 TCP 56 64095 → 9999 [SYN] Seq=0 Win=65535 Len=0 MSS=65495 WS=256 SACK_PERM=1
2 0.000310 127.0.0.1 127.0.0.1 TCP 56 9999 → 64095 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=65495 WS=256 SACK_PERM=1
3 0.000348 127.0.0.1 127.0.0.1 TCP 44 64095 → 9999 [ACK] Seq=1 Ack=1 Win=2619648 Len=0
4 0.054500 127.0.0.1 127.0.0.1 TLSv1.2 327 Client Hello
5 0.054556 127.0.0.1 127.0.0.1 TCP 44 9999 → 64095 [ACK] Seq=1 Ack=284 Win=2619648 Len=0
14 0.117108 127.0.0.1 127.0.0.1 TLSv1.2 134 Server Hello
15 0.117153 127.0.0.1 127.0.0.1 TCP 44 64095 → 9999 [ACK] Seq=284 Ack=91 Win=2619648 Len=0
16 0.117501 127.0.0.1 127.0.0.1 TLSv1.2 883 Certificate
17 0.117527 127.0.0.1 127.0.0.1 TCP 44 64095 → 9999 [ACK] Seq=284 Ack=930 Win=2618624 Len=0
18 0.154454 127.0.0.1 127.0.0.1 TLSv1.2 349 Server Key Exchange
19 0.154510 127.0.0.1 127.0.0.1 TCP 44 64095 → 9999 [ACK] Seq=284 Ack=1235 Win=2618368 Len=0
20 0.155595 127.0.0.1 127.0.0.1 TLSv1.2 281 Certificate Request
21 0.155621 127.0.0.1 127.0.0.1 TCP 44 64095 → 9999 [ACK] Seq=284 Ack=1472 Win=2618112 Len=0
22 0.155776 127.0.0.1 127.0.0.1 TLSv1.2 53 Server Hello Done
23 0.155797 127.0.0.1 127.0.0.1 TCP 44 64095 → 9999 [ACK] Seq=284 Ack=1481 Win=2618112 Len=0
24 0.181028 127.0.0.1 127.0.0.1 TLSv1.2 890 Certificate
25 0.181103 127.0.0.1 127.0.0.1 TCP 44 9999 → 64095 [ACK] Seq=1481 Ack=1130 Win=2618880 Len=0
26 0.231214 127.0.0.1 127.0.0.1 TLSv1.2 86 Client Key Exchange
27 0.231256 127.0.0.1 127.0.0.1 TCP 44 9999 → 64095 [ACK] Seq=1481 Ack=1172 Win=2618880 Len=0
28 0.274682 127.0.0.1 127.0.0.1 TLSv1.2 313 Certificate Verify
29 0.274724 127.0.0.1 127.0.0.1 TCP 44 9999 → 64095 [ACK] Seq=1481 Ack=1441 Win=2618624 Len=0
30 0.277254 127.0.0.1 127.0.0.1 TLSv1.2 50 Change Cipher Spec
31 0.277294 127.0.0.1 127.0.0.1 TCP 44 9999 → 64095 [ACK] Seq=1481 Ack=1447 Win=2618624 Len=0
32 0.278436 127.0.0.1 127.0.0.1 TLSv1.2 89 Finished
33 0.278475 127.0.0.1 127.0.0.1 TCP 44 9999 → 64095 [ACK] Seq=1481 Ack=1492 Win=2618368 Len=0
34 0.283691 127.0.0.1 127.0.0.1 TLSv1.2 50 Change Cipher Spec
35 0.283761 127.0.0.1 127.0.0.1 TCP 44 64095 → 9999 [ACK] Seq=1492 Ack=1487 Win=2618112 Len=0
36 0.284271 127.0.0.1 127.0.0.1 TLSv1.2 89 Finished
37 0.284303 127.0.0.1 127.0.0.1 TCP 44 64095 → 9999 [ACK] Seq=1492 Ack=1532 Win=2618112 Len=0
38 0.286136 127.0.0.1 127.0.0.1 TLSv1.2 84 [TLS segment of a reassembled PDU]
39 0.286178 127.0.0.1 127.0.0.1 TCP 44 9999 → 64095 [ACK] Seq=1532 Ack=1532 Win=2618368 Len=0
40 0.288601 127.0.0.1 127.0.0.1 TLSv1.2 77 [TLS segment of a reassembled PDU]
41 0.288642 127.0.0.1 127.0.0.1 TCP 44 64095 → 9999 [ACK] Seq=1532 Ack=1565 Win=2618112 Len=0
42 1.312272 127.0.0.1 127.0.0.1 TCP 44 64095 → 9999 [RST, ACK] Seq=1532 Ack=1565 Win=0 Len=0
从以上的数据可以清晰的了解整个SSL连接的全过程。当我们想了解服务器和客户端之间传输了什么数据的时候,例如这里的第38行是连接建立之后,客户端给服务器发送一个"Helo World"的信息,第40行是服务器给客户端发送一个"Bye"的信息。当我们点击这两行的时候,wireshark会自动帮我们解密。这样很方便我们进行后续的一些故障排查的工作。