数据抓包分析在软件开发中是经常出现的一种活动, Wireshark
在数据包分析领域是绝对的一哥, 支持的数据协议数不胜数. 如今这些协议中很大一部分更是逐渐使用 TLS
加持的变种, 正常情况下 Wireshark
看到这些数据包也无能为力, 本文来分析事件一种调测阶段常用的解析 TLS
协议包的方法.
本文所提及内容并非强制解开
TLS
数据包, 而是通过一些手段可以得到TLS
握手后的对称加密密钥, 实现解析TLS
数据包的目的.
Pre-Master-Secret Log
这个方法的根基是 openssl
组件可以支持将 密钥信息
单独保存起来, 方便用户做数据调测. 理论上只要使用了 openssl
组件的软件都天然支持, 下面来介绍下使用方法:
操作系统
- 在系统内添加名为
SSLKEYLOGFILE
的环境变量, 值指向本地文件系统的一个文件, 可以是永久的也可以是临时的:
# Windows: 在高级系统设置中手动添加, 或使用命令
setx SSLKEYLOGFILE "%USERPROFILE%\PreMasterSecret.log"
# Linux/Unix:
export SSLKEYLOGFILE=~/PreMasterSecret.log
Wireshark
中配置上SSLKEYLOGFILE
环境变量的值:
首选项 -> Protocols -> TLS -> (Pre)-Master-Secret log filename 中填写上面SSLKEYLOGFILE
的值.
然后, 启动 Wireshark
进行抓包, 通过 OpenSSL
组件新产生的 TLS
数据包正常情况下 Wireshark
就能正常解析出原始内容了.
部分软件
对于一些使用 OpenSSL
的软件, 除了上面的环境变量, 或许还支持特殊的入口.
比如基于 Chromium
内核的浏览器们, 支持使用启动参数 --ssl-key-log-file=%USERPROFILE%\PreMasterSecret.log
来配置 SSLKEYLOGFILE
, 效果是一样的.
RSA Key
相比上面的 Pre-Master-Secret Log
方法, 理论上给 Wireshark
配置服务器私钥应该是更通用的方法, 遗憾的是, 这个方法只支持服务器 密码套件(Cipher Suite)
是 TLS_RSA_XXX
的情况, 且还有如下约束(官方翻译):
- Server端选择的算法不能是(EC)DHE
- 协议版本是SSLv3,(D)TLS 1.0-1.2,不支持 TLS 1.3
- 私钥必须和服务端证书配对,客户端私钥或者根证书私钥都不行
- 会话没有被恢复,握手过程必须包含ClientKeyExchange消息
可以看到约束还挺多, 我这里通过自建 HTTPS
服务器, 强制服务器使用 RSA
密码套件来演示, 在 Wireshark
中配置上服务器的私钥:
首选项 -> Protocols -> TLS -> RSA keys list 中添加密钥文件, IP address
/Prot
/Protocol
可写可不写, Password
需要根据输入的密钥文件决定是否填写.
然后启动抓包就可以了, 可以看到已经解包成功了:
- 客户端使用的
curl
, 可以看到支持的密钥套件挺多的:
- 服务器我强制指定了
RSA
的套件, 可以看到是生效的:
- 解析出来的报文:
其他
解码日志
如果在这里配置上, 可以查看 Wareshark
尝试解密的日志哦, 可以看出是先尝试 RSA keys
然后再尝试使用 Pre-Master-Secret Log
.
为什么即便有私钥 Wireshark
也无法解密 TLS
数据
主要原因就是密钥交换算法:
密钥交换算法目前常用的有 RSA
和 Diffie-Hellman
。
对于密钥交换使用 RSA
算法,pre-master-secret
由客户端生成,并使用公钥加密传输给服务器。
对于密钥交换使用 Diffie-Hellman
算法,pre-master-secret
则通过在 Key Exchange
阶段交换的信息,由各自计算出 pre-master-secret
。所以 pre-master-secret
没有存到硬盘,也没有在网络上传输,wireshark
就无法获取 session key
,也就无法解密应用数据。那我们是否可以反向计算出 pre-master-secret
呢?理论上可以,但是非常困难。
对 Diffie-Hellman
算法感兴趣的可以参考:
https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange