使用临时 Diffie-Hellman 密码套件时如何解密 TLS 消息?我能够从 SSL 客户端公开 premaster secret 和 master secret。使用它,如何解密 Wireshark 中的消息?
使用 DHE_RSA 密码套件时在 Wireshark 中解密 TLS
一些背景知识:当可以计算主密钥(可以从预主密钥派生)时,Wireshark 支持对 SSL 会话进行解密。对于使用 RSA 密钥交换的密码套件,私有 RSA 密钥可用于解密加密的预主密钥。
对于临时 Diffie-Hellman (DHE) 密码套件,RSA 私钥仅用于签署 DH 参数(而不用于加密)。这些参数用于 DH 密钥交换,从而产生共享密钥(实际上是预主密钥,当然在网络上不可见)。
Wireshark 支持多种解密 SSL 的方法:
通过使用私有 RSA 密钥解密预主密钥。适用于 RSA 密钥交换并受上述限制。
使用将标识符映射到主密钥的 SSL 密钥日志文件。可用的标识符是:
- 加密的预主密钥的前 8 个字节(16 个十六进制编码字符)(在 ClientKeyExchange 握手消息中通过线路传输)。(
RSA XXX YYY
,自Wireshark 1.6.0起) - 客户端 Hello 握手消息的随机字段中的 32 个字节(64 个字节的十六进制编码字符)。(
CLIENT_RANDOM XXX YYY
,从Wireshark 1.8.0开始)- 也存在将客户端随机映射到预主密钥(而不是主密钥)的变体。(
PMS_CLIENT_RANDOM XXX ZZZ
,自Wireshark 2.0起) - 存在另一个变体以支持 TLS 1.3 并将客户端随机映射到相应的秘密。
CLIENT_RANDOM
键是CLIENT_EARLY_TRAFFIC_SECRET
、CLIENT_HANDSHAKE_TRAFFIC_SECRET
、或之一SERVER_HANDSHAKE_TRAFFIC_SECRET
,而不是。从Wireshark 2.4 开始。CLIENT_TRAFFIC_SECRET_0
SERVER_TRAFFIC_SECRET_0
- 也存在将客户端随机映射到预主密钥(而不是主密钥)的变体。(
- Server Hello 握手消息的会话 ID 字段。(
RSA Session-ID:XXX Master-Key:YYY
,自Wireshark 1.6.0起) - Client Hello TLS 扩展或 Session Ticket 握手消息中的 Session Ticket。(
RSA Session-ID:XXX Master-Key:YYY
,从Wireshark 1.11.3开始)
- 加密的预主密钥的前 8 个字节(16 个十六进制编码字符)(在 ClientKeyExchange 握手消息中通过线路传输)。(
要为会话生成此类 SSL 密钥日志文件,请SSLKEYLOGFILE
在启动 NSS 应用程序之前将环境变量设置为文件。Linux 的示例 shell 命令:
export SSLKEYLOGFILE=$PWD/premaster.txt
firefox
在 Windows 上,您需要通过cmd
(例如调用setx SSLKEYlOGFILE "%HOMEPATH%\Desktop\premaster.txt"
)或通过系统配置面板设置全局环境变量。完成后,您可以通过图标启动 Firefox。注意: (Linux) 使用 NSS 3.24+ 的 Firefox 用户可能无法使用此方法,因为 Firefox 开发人员默认禁用此方法。
可以在Edit -> Preferences , Protocols -> SSL , field (Pre)-Master-Secret log filename中为 Wireshark 配置 SSL 密钥日志文件(或传递-o ssl.keylog_file:path/to/keys.log
towireshark
或tshark
)。
完成此操作后,您可以解密先前和实时捕获的 SSL 会话。如果您遇到仍然无法解密流量的情况,请检查:
- 关键日志文件路径是否正确(使用绝对路径,以防程序更改工作目录)。
- 密钥日志文件是否实际包含程序的密钥材料。
- Wireshark 是否使用 GnuTLS 编译(我已经使用 GnuTLS 3.2.4 和 libgcrypt 1.5.3 测试了 Wireshark 1.10.1)
- 是否可以解密其他会话。例如,我尝试
https://lekensteyn.nl/
了哪个有效,但使用 Camellia 密码套件的网站失败了。
如果您仍然无法解密所有流量,则 Wireshark 可能包含错误(在我的情况下,它缺少对 Camellia 的支持)。要开始调试,请保存您的捕获并在启用 SSL 日志记录的情况下启动 wireshark:
wireshark -o ssl.debug_file:debug.txt savedcapture.pcapng
加载捕获后,您可以再次关闭程序。(您实际上不需要保存捕获,但它可以更轻松地重现问题并避免日志转储中出现更多噪音。)您可能会看到类似于以下行的内容:
ssl_generate_keyring_material not enough data to generate key (0x33 required 0x37 or 0x57)
这些数字是定义在 中的常数的组合epan/dissectors/packet-ssl-utils.h
:
215-#define SSL_CLIENT_RANDOM (1<<0)
216-#define SSL_SERVER_RANDOM (1<<1)
217:#define SSL_CIPHER (1<<2)
218-#define SSL_HAVE_SESSION_KEY (1<<3)
219-#define SSL_VERSION (1<<4)
220-#define SSL_MASTER_SECRET (1<<5)
221-#define SSL_PRE_MASTER_SECRET (1<<6)
如您所见,我在SSL_MASTER_SECRET
这里缺少 (0x20)。进一步查看日志文件,我还可以找到:
dissect_ssl3_hnd_srv_hello can't find cipher suite 0x88
cipher_suites
中定义的结构中确实缺少此密码套件epan/dissectors/packet-ssl-utils.c
。在研究了 RFC 5932 - Camellia Cipher Suites for TLS之后,我找到了CipherSuite
. 然后应该将生成的补丁提交给 Wireshark,就像我在这里所做的那样:https ://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9144 。稳定的 1.12 系列大大改进了密码套件和 TLS 支持,因此您现在不必手动修补它。
如果您可以“公开 premaster secret”,尽管密钥交换使用短暂的 Diffie-Hellman,那么您就拥有访问客户端或服务器的特权。这是 DHE 的要点之一:实际的密钥交换使用新生成的 DH 密钥对,客户端或服务器都不会将其存储在自己的 RAM 中的任何地方。作为 Wireshark 的被动攻击者,拥有永久服务器密钥的副本不会给您任何帮助,因为它仅用于签名。该密钥可用于模拟服务器,从而发起主动中间人攻击。
不管怎么说,如果您可以访问 premaster secret,那么您也应该可以直接访问明文数据,而不必求助于粗略的数据包捕获;因此,您的问题很奇怪。
总之,后续的数据记录可以通过以下解密标准(或之一的 以前的 版本,如果适用),这是一个有趣的编程工作。这可能是ssldump的源代码可能完成这项任务可以重复使用。