Wireshark 解密 HTTPS
Wireshark 解密 HTTPS
在排查 HTTPS 访问异常、Web Filter/SSL 检测误判、应用层重置、HTTP/2/HTTP/3 行为差异等问题时,仅查看 TLS Application Data 通常无法确认真实请求内容。通过客户端生成 TLS 会话密钥日志(key log file),再将该文件配置到 Wireshark,可以在抓包中还原对应 HTTPS 会话的明文应用层内容。
重要
TLS 会话密钥日志可以解密对应时间段内的 HTTPS 流量,排查完成后应删除 key log 文件,并关闭使用该环境变量启动的浏览器。不要长期在系统全局环境变量中保留 SSLKEYLOGFILE。
解密原理
常用浏览器和部分命令行工具支持通过 SSLKEYLOGFILE 环境变量把 TLS 会话密钥写入文本文件。Wireshark 读取该文件后,可以根据抓包中的 TLS 握手信息匹配会话密钥,并解密后续应用层数据。

上图是 key log 解密的流程示意:key log 文件、抓包文件和浏览器访问必须属于同一次 TLS 会话。如果抓包开始得太晚,或 key log 来自另一次访问,Wireshark 就无法把两者匹配起来。
该方法适用于受控测试终端发起的流量,不能用于任意历史抓包或任意第三方终端流量。使用时需要满足以下条件:
- 终端应用必须支持
SSLKEYLOGFILE,常见可用应用包括 Chrome、Firefox、Chromium 版 Edge、curl 等。Safari 通常不适合使用此方法。 - 抓包中需要包含完整 TLS 握手,建议先开始抓包,再打开浏览器访问目标网站。
- key log 文件必须来自发起该 HTTPS 会话的客户端应用。
- 如果浏览器已经在运行,新的浏览器窗口可能会复用旧进程,导致环境变量不生效。建议先完全退出浏览器,或使用独立的临时浏览器配置目录。
FortiGate 抓包注意事项
如果只是在 FortiGate 上转发普通 HTTPS 流量,并未开启 SSL deep-inspection,客户端与服务器之间是一条端到端 TLS 会话。此时只要 FortiGate 抓包中包含该 TLS 握手,客户端生成的 key log 文件通常可以解密 FortiGate 上抓到的对应会话。
如果防火墙策略开启了 SSL deep-inspection,FortiGate 会把连接拆成两段 TLS:
- 客户端 ↔ FortiGate:客户端浏览器生成的 key log 可以解密这一侧抓包。
- FortiGate ↔ 服务器:这是 FortiGate 重新发起的 TLS 会话,客户端浏览器的 key log 无法解密这一侧抓包。
因此在 SSL deep-inspection 场景中,如果要结合客户端 key log 分析浏览器真实请求,应优先抓取客户端到 FortiGate 这一侧的流量。如果需要判断 FortiGate 到服务器侧的 TLS 行为,应以 TLS 握手、证书、SNI、RST/FIN、FortiGate 日志和 SSL Debug 等信息辅助分析。

上图是 SSL deep-inspection 场景中的解密边界示意:未开启 SSL deep-inspection 时,客户端 key log 对 FortiGate 转发路径上的同一 TLS 会话有效;开启 SSL deep-inspection 后,客户端 key log 只适用于客户端到 FortiGate 这一侧,不能解密 FortiGate 到服务器这一侧。
抓包时建议抓完整报文并保留时间戳,例如:
diagnose sniffer packet any "host 192.168.10.10 and (tcp port 443 or udp port 443)" 6 0 l192.168.10.10为测试客户端 IP。- 如果确认只分析传统 HTTPS/TCP,可以只抓
tcp port 443。 - 如果浏览器可能使用 HTTP/3/QUIC,需要同时抓
udp port 443,或者在测试浏览器中临时禁用 QUIC。 - 使用 CLI sniffer 格式 6 抓到的文本,可参考“故障排查 → Sniffer 工具 → 使用 Wireshark 打开抓包文件”和“故障排查 → Sniffer 工具 → Wireshark 显示抓包接口和方向”章节转换为 PCAP。
Windows 配置方法
以下示例使用 PowerShell 临时启动 Chrome。该环境变量只对当前 PowerShell 及由它启动的进程生效,不会写入系统全局环境变量。
关闭所有已经运行的 Chrome/Firefox/Edge 浏览器进程。
打开 PowerShell,创建 key log 文件,并设置
SSLKEYLOGFILE。$desktop = [Environment]::GetFolderPath("Desktop") $keylog = Join-Path $desktop "tls_keylog.txt" New-Item -ItemType File -Force $keylog $env:SSLKEYLOGFILE = $keylog $env:SSLKEYLOGFILE从当前 PowerShell 启动浏览器。
Start-Process chrome.exe
提示
如果需要避免复用原有 Chrome 用户会话,可以使用临时用户目录启动 Chrome。
Start-Process chrome.exe -ArgumentList "--user-data-dir=$env:TEMP\wireshark-chrome-tls"如果测试目标只需要传统 HTTPS/TCP,而不希望浏览器优先使用 QUIC/HTTP/3,可以临时增加
--disable-quic参数。Start-Process chrome.exe -ArgumentList "--disable-quic --user-data-dir=$env:TEMP\wireshark-chrome-tls"先在 FortiGate 或本机 Wireshark 开始抓包,再使用刚启动的浏览器访问目标 HTTPS 网站。
确认
tls_keylog.txt中已经写入内容。正常情况下,文件中会出现类似CLIENT_RANDOM、CLIENT_HANDSHAKE_TRAFFIC_SECRET、SERVER_TRAFFIC_SECRET的记录。
macOS 配置方法
关闭所有已经运行的 Chrome/Firefox/Edge 浏览器进程。
打开 iTerm2,创建 key log 文件,并设置
SSLKEYLOGFILE。keylog="$HOME/Desktop/tls_keylog.txt" touch "$keylog" export SSLKEYLOGFILE="$keylog"从当前 iTerm2 启动 Chrome。
open -na "Google Chrome"
提示
如果需要避免复用原有 Chrome 用户会话,可以使用临时用户目录启动 Chrome。
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=/tmp/wireshark-chrome-tls如果测试目标只需要传统 HTTPS/TCP,而不希望浏览器优先使用 QUIC/HTTP/3,可以临时增加
--disable-quic参数。/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-quic --user-data-dir=/tmp/wireshark-chrome-tls先在 FortiGate 或本机 Wireshark 开始抓包,再使用刚启动的浏览器访问目标 HTTPS 网站。
确认
tls_keylog.txt中已经写入内容。tail "$HOME/Desktop/tls_keylog.txt" CLIENT_HANDSHAKE_TRAFFIC_SECRET e31fbfd0c6d25383624c55e1571736a6085f1b3d7c0c718b4657cf2dd5b8741d 093c6bb4ca895a7ee4cc6a1ed3e7d2acf01b29be903e74c7c92992a819226965 SERVER_HANDSHAKE_TRAFFIC_SECRET e31fbfd0c6d25383624c55e1571736a6085f1b3d7c0c718b4657cf2dd5b8741d 20eba12d107f8979ebeb615c67ed18ddfdd72404c6c07c310bc8a081b0c69901 ......
Wireshark 加载 key log 文件
使用 Wireshark 打开抓包文件。
打开 TLS 协议首选项。

- Windows:进入
Edit → Preferences → Protocols → TLS。 - macOS:进入
Wireshark → Preferences → Protocols → TLS。
- Windows:进入
在
(Pre)-Master-Secret log filename中选择前面生成的 key log 文件。- Windows:选择 PowerShell 中
$env:SSLKEYLOGFILE输出的完整路径,例如D:\Desktop\tls_keylog.txt。 - macOS 示例:
/Users/summerice/Desktop/tls_keylog.txt
- Windows:选择 PowerShell 中
点击 OK/Apply 后,Wireshark 会重新解析当前抓包。
解密成功后,原本只显示为 TLS
Application Data的报文会解析出 HTTP、HTTP/2 或 HTTP/3 等上层协议字段。也可以右键对应报文,使用Follow → TLS Stream、Follow → HTTP Stream、Follow → HTTP/2 Stream等功能查看会话内容。
常见问题
key log 文件为空
常见原因如下:
- 浏览器不是从设置了
SSLKEYLOGFILE的 PowerShell/iTerm2 中启动的。 - 原浏览器进程没有完全退出,新窗口复用了原进程。
- 使用的应用不支持
SSLKEYLOGFILE,例如 Safari。 - key log 文件路径不可写。
处理方法:
- 完全退出浏览器,必要时在任务管理器/活动监视器中确认进程已结束。
- 重新设置
SSLKEYLOGFILE。 - 从同一个 PowerShell/iTerm2 启动浏览器。
- 使用独立临时用户目录启动浏览器,避免复用原有进程。
Wireshark 仍然只能看到 Application Data
常见原因如下:
- 抓包开始得太晚,没有抓到 TLS Client Hello 和 Server Hello。
- 抓包文件和 key log 文件不是同一次访问生成的。
- FortiGate 开启了 SSL deep-inspection,但抓取的是 FortiGate 到服务器侧的 TLS 会话。
- 浏览器实际使用的是 QUIC/HTTP/3,但抓包只抓了 TCP/443。
- Wireshark 中
(Pre)-Master-Secret log filename路径配置错误。
处理方法:
- 停止抓包并关闭浏览器。
- 清空或重新创建 key log 文件。
- 先开始抓包,再启动浏览器访问目标网站。
- 确认抓包过滤条件包含实际协议,例如
tcp port 443或udp port 443。 - 在 Wireshark 中重新选择 key log 文件,并重新打开抓包文件验证。
HTTPS 经过 FortiGate NAT 后还能解密吗
可以。key log 的匹配依赖 TLS 握手中的会话信息,不依赖客户端原始 IP 是否被 FortiGate SNAT。但抓包过滤条件需要考虑 NAT 前后地址变化,避免只抓到单侧报文。相关过滤思路可参考“故障排查 → Sniffer 工具 → Sniffer 过滤条件的合理使用”章节。
是否可以用服务器私钥解密 HTTPS
现代 HTTPS 通常使用 ECDHE/DHE 等具备前向保密能力的密钥交换方式,仅凭服务器私钥通常无法解密历史会话。除非满足较老的 RSA 密钥交换等特定条件,否则应优先使用 key log 文件方式。
清理信息
排查完成后,建议执行以下清理动作:
关闭通过 PowerShell 启动的浏览器。
删除 key log 文件。
$desktop = [Environment]::GetFolderPath("Desktop") $keylog = Join-Path $desktop "tls_keylog.txt" Remove-Item $keylog -ErrorAction SilentlyContinue如果使用了临时 Chrome 用户目录,可一并删除。
Remove-Item "$env:TEMP\wireshark-chrome-tls" -Recurse -Force -ErrorAction SilentlyContinue
关闭通过 iTerm2 启动的浏览器。
删除 key log 文件。
rm -f "$HOME/Desktop/tls_keylog.txt"如果使用了临时 Chrome 用户目录,可一并删除。
rm -rf /tmp/wireshark-chrome-tls