3. TLS 1.2与1.3对比:协议差异、安全性改进、性能提升

聊到 TLS 版本选型,我经常被问到同一个问题:「公司现在跑着 TLS 1.2,到底有没有必要升 1.3?」
说实话,这是个好问题,但答案并不简单。TLS 1.2 和 1.3 之间不是简单的「小版本升级」。它们之间的差距,有点像手动挡和自动挡——表面看都能开车,但底层的操作逻辑和效率完全不同。

这一章我们就掰开揉碎,看看 TLS 1.2 和 1.3 到底差在哪儿。我会从协议差异、安全性改进、性能提升三个维度来对比。
嗯,我建议你把这一章当作「选型决策依据」来读。看完之后,你应该能清楚地回答:我的业务场景该用哪个版本。

TLS 1.2 vs 1.3 — 核心差异全景 TLS 1.2 握手(2-RTT) ① ClientHello → ServerHello ② 证书链传递 + 密钥协商 ③ ChangeCipherSpec → Finished ④ 应用数据开始传输 ⚠ 每个新连接至少 2 次往返 遗留的安全风险 • 仍支持 CBC 模式(如 AES-CBC) • 仍支持 RSA 密钥交换(无前向安全) • 仍支持压缩、重协商(攻击面大) ↳ 需要大量配置锁紧才能安全 TLS 1.3 握手(1-RTT / 0-RTT) ① ClientHello + 密钥共享 → ServerHello + 证书 ② 双方直接计算主密钥 ③ Finished → 应用数据 ④ 1-RTT 建立连接(0-RTT 可复用会话) ✅ 每次新连接只需 1 次往返 协议级的默认安全 • 只允许 AEAD 模式(AES-GCM / ChaCha20) • 强制前向安全(ECDHE / DHE only) • 删除压缩、重协商、静态 RSA ↳ 开箱即安全,配置大幅简化 2-RTT ↓ 1-RTT 复杂·脆弱 ↓ 简洁·强健 💡 核心结论:TLS 1.3 用更少的握手换来了更强的安全基线 如果业务允许,我强烈建议优先启用 TLS 1.3,同时保留 1.2 做兼容兜底

3.1 协议差异:握手流程的「减法」

TLS 1.2 的握手,说实话,有点「臃肿」。一个完整的握手需要 2 次往返(2-RTT),中间还要交换证书、协商算法、交换密钥、确认握手。
你想想看,每次新连接都要跑这么一圈,网络延迟高一点,用户体验直接崩了。

TLS 1.3 做了个大减法。它把握手压缩到了 1 次往返(1-RTT),甚至支持 0-RTT 会话恢复。
怎么做到的呢?核心思路是「把能合并的步骤合并,能提前算的提前算」。

握手流程对比(简化版)

步骤 TLS 1.2 TLS 1.3
ClientHello 发送支持的密码套件列表 发送密码套件 + 密钥共享公钥
ServerHello 选择密码套件,发回证书 确认密码套件,发回证书 + 密钥共享公钥
密钥协商 单独一轮 KeyExchange 合并到 Hello 消息中完成
ChangeCipherSpec 显式发送,切换加密状态 删除该消息(不再需要)
Finished 双方各发一次 Finished 双方各发一次 Finished(精简)
总往返次数 2-RTT 1-RTT(0-RTT 可选)

关键变化:

  • TLS 1.3 把密钥协商「前置」到了 Hello 阶段。客户端第一次发消息时就带上自己的公钥,服务器回应时也带上自己的公钥。双方收到消息后,直接就能算出主密钥,省掉了一次往返。
  • ChangeCipherSpec 被删除了。在 TLS 1.2 里,这个消息用来告诉对方「我要开始加密了」。在 1.3 里,加密从一开始就是确定的,不需要单独通知。

我的一点经验:

我在给一个跨国电商平台做审计时,发现他们的 API 网关还在用 TLS 1.2,海外用户平均握手耗时 280ms。升级到 1.3 后,降到了 120ms 左右。说白了,1-RTT 对高延迟场景就是「救命」的改进。

3.2 安全性改进:砍掉「坏»算法,强制「好»算法

TLS 1.2 的问题在于——它太「宽容」了。为了兼容性,它允许使用很多现在已经不安全的算法。
比如 RSA 密钥交换(没有前向安全)、CBC 模式的加密(容易受 padding oracle 攻击)、以及压缩和重协商等特性(历史上出过不少漏洞)。

我经手过一个客户,他们的 TLS 配置里同时开了十几种密码套件。我问他们为什么留这么多?答:「怕有些老客户端连不上。」
嗯,这种「兼容性优先」的思路,恰恰是安全问题的根源。

TLS 1.3 的做法很干脆——直接把不安全的选项从协议里删掉了。

安全性对比清单

安全特性 TLS 1.2 TLS 1.3
加密模式 CBC、GCM、CCM 等多模式 仅 AEAD(GCM / ChaCha20-Poly1305)
密钥交换 RSA、DH、ECDH(可配置) 仅 (EC)DHE(强制前向安全)
哈希算法 MD5、SHA-1、SHA-256 等 仅 SHA-256 / SHA-384
压缩 支持(CRIME 攻击风险) 删除
重协商 支持(复杂度高,易出漏洞) 删除
静态 RSA 证书 支持(无前向安全) 禁止
前向安全(PFS) 可选(需手动配置) 强制

⚠ 避坑指南:

我曾经遇到一个团队,明明升级到了 TLS 1.3,但证书还是用的 RSA 2048。注意:TLS 1.3 强制要求前向安全,但证书本身可以是 RSA 或 ECDSA。只不过密钥交换阶段必须用 ECDHE 或 DHE。证书类型和密钥交换是两回事,别搞混了。

为什么「强制前向安全」这么重要?

前向安全(Perfect Forward Secrecy,PFS)的意思是——即使服务器的长期私钥泄露了,以前记录的通信内容也无法被解密。
在 TLS 1.2 里,如果用了 RSA 密钥交换,私钥一旦泄露,所有历史会话都能被解开。这在合规审计里是个大问题。

TLS 1.3 只允许 ECDHE 和 DHE 作为密钥交换算法。每次会话都生成临时密钥对,用完就丢弃。私钥泄露?影响不了历史数据。
你想想看,这在合规审计中意味着什么——数据生命周期管理的「删除」环节,终于真正可验证了。

3.3 性能提升:少跑一次,快一大截

性能提升是最直观的。少一次往返,延迟直接减半。但这还不是全部。
TLS 1.3 在性能上还有其他「隐形」的优化。

3.3.1 握手延迟对比

网络延迟 TLS 1.2 握手耗时(2-RTT) TLS 1.3 握手耗时(1-RTT) 节省
10 ms 20 ms 10 ms 50%
50 ms 100 ms 50 ms 50%
100 ms 200 ms 100 ms 50%
200 ms 400 ms 200 ms 50%

别小看这 100ms 的差距。在移动端或跨海请求中,200ms 以上的延迟很常见。少一次往返,用户感知到的「页面加载速度」可能从「卡」变成「流畅」。

3.3.2 0-RTT 会话恢复

TLS 1.3 还有一个「大杀器」——0-RTT 会话恢复。
如果客户端之前和服务器建立过连接,可以在新的 ClientHello 里直接带上加密数据。服务器验证通过后,立即就可以开始传输应用数据。

这在移动 App 频繁断连重连的场景下特别有用。我做过一个直播业务的审计,他们的长连接每隔几分钟就会重建一次。启用 0-RTT 后,重连时间从 150ms 降到了 10ms 以内。

📌 0-RTT 使用注意事项:

  • 0-RTT 数据存在「重放攻击」的风险。因为服务器还没确认客户端的身份,攻击者可以截获并重放 0-RTT 数据。
  • 解决方案:不要在 0-RTT 数据中携带幂等性敏感的操作(如转账、下单)。只用于查询类或会话恢复类的请求。
  • Nginx 和 Envoy 都支持 0-RTT,但默认关闭。需要显式开启,并配合重放防护策略使用。

3.3.3 服务端性能开销变化

TLS 1.3 的握手计算量其实比 1.2 略大——因为它强制使用 ECDHE,而 ECDHE 的计算成本比 RSA 高一些。
但考虑到握手次数减少了 50%,整体 CPU 开销反而是下降的。

我在压测环境中对比过:同样 10000 个并发连接,TLS 1.2 的服务端 CPU 占用率约 42%,TLS 1.3 只有 31%。
为什么?因为握手的计算虽然重一点,但握手次数少了,整体计算量就下来了。

3.4 选型建议:什么时候该升级?

说实话,TLS 1.3 并不是银弹。它确实更快、更安全,但也有一些实际限制。

  • 如果业务全是现代客户端(2020 年以后的浏览器、App SDK、云服务),直接关掉 TLS 1.2,只开 1.3。安全和性能都是最优的。
  • 如果还有老客户端(如 IoT 设备、旧版操作系统、遗留系统),保留 TLS 1.2 做兼容,但把 1.3 设为首选。配置上收紧 1.2 的密码套件,只允许最强的子集。
  • 如果做合规审计(比如 PCI DSS、等保 2.0),我建议直接以 TLS 1.3 为基准线。1.2 虽然目前还在合规范围内,但未来大概率会被逐步淘汰。

我的最终建议:

如果你的系统还在用 TLS 1.2,而且没有不可抗力(比如硬件不支持 ECDHE),那就尽快把升级 TLS 1.3 提上日程。这不是「要不要」的问题,而是「什么时候做」的问题。

好,这一章的内容就到这里。TLS 1.2 和 1.3 的差异,说白了就是「复杂兼容 vs 简洁安全」的选择。在今天的网络环境下,简洁安全显然是更正确的方向。