3. TLS 1.2与1.3握手差异

这一章咱们聊聊握手差异。说实话,我刚开始接触TLS 1.3的时候,第一反应是——握手怎么变这么快了?以前调个TLS问题抓包看四个来回,现在唰唰两下就结束了。变化确实大,但对我们做审计日志的人来说,真正要命的不是速度,而是能看到的东西变少了。

3.1 握手轮次:从2-RTT到1-RTT

先解释下RTT。说白了就是一次"你问我答"的往返时间。TLS 1.2完整握手需要2个RTT,TLS 1.3砍到了1个。为什么能做到?核心在于把密钥协商提前了。

TLS 1.2的流程是:ClientHello → ServerHello+证书 → 客户端密钥交换 → 双方确认。每一步都得等对方回应了才能继续。而TLS 1.3在ClientHello里就把key_share带过去了,服务端收到后直接算出密钥,ServerHello之后的所有消息都是加密传输的。

你想想看,一个RTT的差距在跨国访问场景下意味着什么?延时直接减半。我在帮一家跨境电商做审计平台时遇到过,他们全球有几十个边缘节点,TLS 1.2握手的耗时占整体连接建立的60%以上。升级到1.3后,握手时间平均下降了40%多。

下面这张图把两个版本的握手流程放在一起对比,差异一目了然。

TLS 1.2 vs TLS 1.3 握手流程对比 TLS 1.2 (2-RTT) ① ClientHello ② ServerHello + Certificate + ServerHelloDone ③ ClientKeyExchange + CCS + Finished ④ ChangeCipherSpec + Finished TLS 1.3 (1-RTT) ① ClientHello + key_share ② ServerHello + EncryptedExtensions + Certificate + CertVerify + Finished ③ Finished + Application Data key_share 提前协商 ServerHello 后全加密 减少 1 个 RTT TLS 1.3 完整握手仅需 1-RTT,比 TLS 1.2 减少 1 个往返

从图上可以清楚看到,TLS 1.2需要4次消息交互,TLS 1.3压缩到了3次。但真正关键的是——TLS 1.3的ServerHello之后的所有消息都是加密的。这一点对审计日志的影响非常大,下面细说。

核心差异速记:TLS 1.2在握手完成前所有消息都是明文的;TLS 1.3在ServerHello之后就进入加密状态,证书、服务端确认等信息全部加密传输。

3.2 ServerHello的"加密革命"

我个人觉得,ServerHello的变化是TLS 1.3握手里最容易被忽视但影响最大的改动。为什么?

在TLS 1.2中,ServerHello是明文的。你抓个包就能看到服务端选的密码套件、版本号、以及后面跟的证书链。审计工具可以直接从网络流量里提取这些信息。

但在TLS 1.3里,ServerHello虽然还是明文(用于协商版本和密码套件),但紧随其后的EncryptedExtensions、Certificate、CertVerify全部加密。这意味着什么?

  • 证书信息不再可见:你从抓包里看不到服务端发了什么证书
  • 握手完成确认加密:Finished消息也是加密的,没法直接验证
  • 审计日志的采集点需要迁移:从网络层迁移到服务端内部

我记得有一次帮一家银行做合规审计,他们的安全团队习惯用Wireshark抓TLS握手包来验证证书链。升级到TLS 1.3后,突然发现抓包里看不到证书了,还以为配置有问题。查了半天才反应过来——不是配置问题,是协议本身变了。

那怎么办?审计日志不能再只依赖网络抓包了。得从服务端的TLS层直接输出事件日志,比如OpenSSL的日志回调、Nginx的ssl握手日志、或者应用层主动上报的握手事件。

3.3 审计日志需要关注的变化

讲清楚原理后,咱们直接看审计日志层面要改什么。我列了个表,方便你对照检查现有的日志字段。

审计维度 TLS 1.2(旧日志) TLS 1.3(新日志) 影响说明
握手完成时间 2-RTT 时长 1-RTT 时长 基线需要重新标定,超时阈值要调整
密码套件协商 ServerHello 明文可见 ServerHello 明文可见 变化不大,但套件列表变了(移除了很多不安全套件)
证书链信息 抓包直接提取 加密不可见,需服务端日志 日志采集方式必须改
密钥交换参数 ClientKeyExchange 明文 key_share 在 ClientHello 中 新增字段记录 key_share 类型
握手失败原因 Alert 明文 Alert 加密 失败排查难度增加,依赖服务端日志
Session Resumption Session ID 明文 PSK 加密传输 需记录 PSK 标识,而非 Session ID

我给你看一个实际的审计日志例子。下面是我在项目中用过的TLS 1.3握手完成事件的JSON格式日志。

{
  "timestamp": "2025-03-21T14:32:18.721Z",
  "event": "tls_handshake_completed",
  "version": "TLSv1.3",
  "client_ip": "203.0.113.42",
  "server_name": "api.example.com",
  "cipher_suite": "TLS_AES_128_GCM_SHA256",
  "key_share_group": "x25519",
  "certificate_serial": "0x3A1F9B2C8D4E6F01",
  "certificate_issuer": "CN=Example Root CA, O=Example Inc",
  "handshake_rtt_ms": 42,
  "psk_used": false,
  "source": "server_side_tls_log"
}

注意看source字段——我特意加了这个标记。因为证书信息不再能从网络包拿到,必须标明数据来源是"服务端TLS日志",方便审计时做溯源。

我的建议:在TLS 1.3的审计日志里,额外记录 key_share_group 和 psk_used 两个字段。前者反映密钥交换算法,后者标识是否复用了之前的会话。这两个字段在排查性能问题和安全合规时非常有用。

3.4 避坑指南

说几个我踩过的坑,你部署的时候可以留意。

  • 不要用TLS 1.2的日志模板套1.3:我见过有人直接把旧模板拿来用,结果证书字段全是空值。原因就是证书信息已经加密了,网络层采集不到。
  • 注意密钥更新事件:TLS 1.3支持在握手完成后更新通信密钥(Key Update)。这个事件在1.2里没有,审计系统如果没处理,可能漏掉关键的安全事件。
  • 0-RTT的坑:TLS 1.3的0-RTT虽然快,但存在重放攻击风险。如果你们业务用了0-RTT,审计日志里一定要记录是否为"early data",方便安全团队做重放检测。

⚠️ 特别提醒:如果你现有的审计系统依赖网络探针采集TLS握手信息,升级到TLS 1.3后会发现大量字段丢失。这不是系统坏了——是协议本身不让你看了。赶紧把数据源切换到服务端TLS日志接口,或者用eBPF在内核态做hook采集。

嗯,这一章的核心就这些。总结下来就三句话:轮次少了、ServerHello之后加密了、审计日志的采集方式要跟着变。把握好这三点,TLS 1.3的审计工作就不会走偏。