引言
TLS 1.3(RFC 8446)于 2018 年正式发布,相比 TLS 1.2 在安全性、性能和隐私保护方面都有重大改进。对于运维和开发人员来说,最直观的感受往往来自抓包分析——当你用 Wireshark 分别捕获 TLS 1.2 和 TLS 1.3 的握手流量时,会发现两者的报文结构和交互轮次截然不同。本文将从 Wireshark 抓包的角度,逐层拆解这两种协议握手过程的差异,帮助你快速定位和排查 HTTPS 连接问题。
抓包环境准备
在开始分析之前,需要准备以下环境:
- Wireshark 3.0+:低版本对 TLS 1.3 的支持不完善,建议使用最新稳定版。
- 测试工具:
curl(支持--tlsv1.2和--tlsv1.3参数)、浏览器或openssl s_client。 - 密钥日志:在客户端设置
SSLKEYLOGFILE环境变量,将会话密钥导出,Wireshark 配置该文件后即可解密 TLS 1.3 的应用数据。
export SSLKEYLOGFILE=/tmp/sslkeylog.log
curl --tlsv1.3 -v https://example.com -o /dev/null
在 Wireshark 中,通过 Preferences → Protocols → TLS → (Pre)-Master-Secret log filename 加载密钥日志文件,即可解密流量。
TLS 1.2 握手流程回顾
TLS 1.2 的完整握手需要 2 个 RTT(往返时延),典型报文序列如下:
- Client Hello:客户端发送支持的密码套件列表、随机数、扩展字段。
- Server Hello:服务器选定密码套件,返回随机数。
- Certificate:服务器发送证书链。
- Server Key Exchange:发送密钥交换参数(如 ECDHE 公钥)。
- Server Hello Done:服务器握手消息结束标记。
- Client Key Exchange:客户端发送密钥交换参数。
- Change Cipher Spec:客户端通知切换到加密模式。
- Encrypted Handshake Message:客户端 Finished 消息(加密)。
- Change Cipher Spec:服务器通知切换加密。
- Encrypted Handshake Message:服务器 Finished 消息(加密)。
在 Wireshark 中,你可以清晰地看到 Server Hello 之后紧跟着 Certificate、Server Key Exchange 等明文报文,密码套件协商结果也直接可读。由于密钥交换参数在握手阶段明文传输(虽然本身是公钥),整个握手过程的消息类型和顺序一目了然。
TLS 1.3 握手流程解析
TLS 1.3 对握手做了大幅精简,完整握手仅需 1 个 RTT,主要变化包括:
- Client Hello:客户端在第一个报文中就携带密钥共享(key_share)扩展,猜测服务器可能支持的组并提前发送公钥。
- Server Hello:服务器选定密钥共享组,返回自己的公钥。此时双方已经可以计算出共享密钥。
- {Encrypted Extensions}:此后所有握手消息全部加密。
- {Certificate}:加密传输。
- {Certificate Verify}:加密传输。
- {Finished}:加密传输。
- {Finished}:客户端完成。
注意花括号表示该消息在 Wireshark 中默认显示为 Application Data,只有配置了密钥日志后才能解密查看。
关键差异在于:Server Hello 之后的所有握手消息都被加密。这意味着在未配置密钥日志的情况下,你在 Wireshark 中只能看到 Client Hello 和 Server Hello 两个明文报文,其余全部是 Application Data。这是 TLS 1.3 隐私保护增强的直接体现——中间人无法再窥探证书信息和密码套件细节。
核心差异对比
| 对比维度 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| 握手 RTT | 2-RTT | 1-RTT(支持 0-RTT) |
| 明文握手消息 | Client Hello、Server Hello、Certificate、Server Key Exchange 等 | 仅 Client Hello、Server Hello |
| 密钥交换 | 独立的消息交换阶段 | 通过 key_share 扩展在 Hello 中完成 |
| 密码套件 | 包含密钥交换、认证、加密、MAC 算法 | 仅包含 AEAD 加密和哈希算法 |
| Change Cipher Spec | 必需 | 兼容性保留,实际忽略 |
| 会话恢复 | Session ID / Session Ticket | PSK 预共享密钥 |
| 前向安全 | 可选(取决于套件) | 强制 |
在 Wireshark 中,这些差异表现为:
- 报文数量:TLS 1.2 握手通常有 10+ 个报文,TLS 1.3 只有 6 个左右(含加密消息)。
- 可读性:TLS 1.2 可看到证书链和密钥交换参数,TLS 1.3 默认全部加密。
- Server Hello 扩展:TLS 1.3 的 Server Hello 中会包含
supported_versions、key_share等扩展,而 TLS 1.2 没有supported_versions扩展(或值为 1.2)。
Wireshark 过滤技巧
为了快速区分和定位 TLS 1.3 流量,可以使用以下显示过滤器:
# 过滤所有 TLS 握手消息
tls.handshake
# 过滤 TLS 1.3 的 Client Hello(supported_versions 扩展包含 0x0304)
tls.handshake.extensions_supported_version == 0x0304
# 过滤 TLS 1.2 的 Client Hello
tls.handshake.extensions_supported_version == 0x0303
# 过滤特定 SNI
tls.handshake.extensions_server_name == "example.com"
此外,在 Wireshark 的 Protocol Hierarchy 统计中,TLS 1.3 流量的 Application Data 占比会明显高于 TLS 1.2,因为大部分握手消息也被归类为 Application Data。
实际排查中的注意事项
- 中间设备干扰:部分老旧防火墙或负载均衡设备可能不支持 TLS 1.3,导致握手失败。此时在 Wireshark 中会看到 Client Hello 后直接出现 TCP RST 或超时。
- 0-RTT 风险:TLS 1.3 的 0-RTT 模式虽然快,但存在重放攻击风险。Wireshark 中 0-RTT 数据表现为 Client Hello 后紧跟 Early Data,需谨慎启用。
- 密钥日志配置:如果无法解密 TLS 1.3 流量,首先检查
SSLKEYLOGFILE是否生效,以及 Wireshark 是否加载了正确的密钥日志文件。注意该文件包含会话密钥,生产环境需妥善保管。
总结
TLS 1.3 在握手效率上的提升是显而易见的:1-RTT 完成握手、握手消息全面加密、密码套件大幅精简。从 Wireshark 抓包的角度看,最直观的变化就是“能看到的明文变少了”——这既是性能优化,也是隐私保护的进步。掌握两种协议在抓包中的表现差异,不仅能帮助你快速判断连接使用的是哪个版本,还能在排查 HTTPS 故障时更有针对性地定位问题。建议在日常运维中养成配置密钥日志的习惯,这样才能充分发挥 Wireshark 对 TLS 1.3 的解密分析能力。
未经允许不得转载:任鹏个人博客 » 用 Wireshark 拆解 TLS 1.2 与 TLS 1.3 握手过程的差异


朋友圈点赞图在线生成源码