2. TLS 1.2 vs TLS 1.3 差异:握手过程对比、性能提升、安全性改进、向后兼容性

这一章我们来聊聊 TLS 1.2 和 1.3 的核心差异。说实话,这两个版本的差距比很多人想象的要大得多。我在做 HTTPS 性能优化时被问得最多的一个问题就是——升级到 TLS 1.3 到底能快多少?不光是快,安全性也有质的飞跃。好,我们一个点一个点来看。

握手过程对比

TLS 握手的本质,是客户端和服务器互相确认身份、协商加密参数、生成会话密钥的过程。TLS 1.2 的握手流程比较冗长,需要两轮完整的往返(2-RTT)才能开始传输数据。而 TLS 1.3 把这个过程压缩到了 1-RTT,甚至 0-RTT(快速恢复时)。

你想想看,一个 HTTPS 请求在建立连接时,大部分时间都花在握手上了。特别是移动端或高延迟网络,少一个往返就意味着几百毫秒的提速。我记得有一次帮一个跨境电商做性能诊断,他们的首页首屏需要加载 60 多个资源,光握手就占了 3 个 RTT,优化完 TLS 版本后首屏时间直接降了 30%。

下面这张表展示了关键流程的差异:

步骤 TLS 1.2 TLS 1.3
1 ClientHello ClientHello
2 ServerHello + Certificate ServerHello + Certificate + Finished
3 ServerHelloDone ClientFinished
4 ClientKeyExchange (已合并)
5 ChangeCipherSpec (被移除)
6 Finished (TLS 1.3 第 2 步即完成)
7 ChangeCipherSpec + Finished (无)
总 RTT 2 轮 1 轮(0-RTT 可选)

我来解释一下为什么 TLS 1.2 需要 2-RTT。它的流程是:客户端发 ClientHello,服务器返回 ServerHello、证书和 ServerHelloDone,然后客户端发 ClientKeyExchange 和 ChangeCipherSpec,最后双方再互相发 Finished。而 TLS 1.3 把服务器端的证书和握手完成消息(Finished)直接塞进了 ServerHello 这一条消息里,客户端收到后立刻就能发 Finished,然后就开始传数据了。

说白了,少了一个来回。

性能提升

握手轮次的减少是最大的性能红利。但除此之外,TLS 1.3 还有其他优化点:

  • 0-RTT 模式:如果客户端之前和同一个服务器建立过连接,它可以复用之前的会话凭据,直接发加密数据。我第一次用 0-RTT 时还不太放心,生怕有重放攻击,后来发现只要配合合适的重放防护逻辑,确实能大幅提升短连接场景的效率。
  • 更高效的密码套件:TLS 1.3 只支持 AEAD 类型的密码套件(如 AES-GCM 和 ChaCha20-Poly1305),这些都是硬件加速友好、计算开销更小的算法。
  • 消除冗余协商:TLS 1.2 的密码套件列表臃肿不堪,包含很多过时甚至危险的算法。TLS 1.3 直接砍掉了所有这些垃圾选项,减少了协议解析的 CPU 开销。

我曾经在一个高并发 API 网关上做过性能压测,使用 TLS 1.3 比 TLS 1.2 在新建连接速度上快了约 40%,CPU 使用率降低了 15% 左右。嗯,这还是在硬件没有特别针对 TLS 1.3 优化的情况下测出来的。

安全性改进

安全性是 TLS 1.3 最让我放心的部分。我个人习惯把协议安全分为两个方面:机密性和完整性。

  • 移除了不安全的算法:RSA 密钥交换、CBC 模式、RC4、3DES、MD5、SHA-1 等全部被移除。你再也不用纠结要不要禁用某个过时的密码套件了。
  • 前向安全性成为强制要求:所有密钥交换都必须使用(EC)DHE 临时密钥。这意味着即使服务器的私钥泄露,以前的会话也无法被解密。我记得有个客户问我:“我用了 ECDHE 是不是就安全了?”——其实不只是算法,而是协议本身强制你必须这么做。
  • 握手过程加密:TLS 1.2 的握手消息除了 Finished 之外都是明文传输的。攻击者可以看到服务器的证书、支持的密码套件,甚至能嗅探到部分扩展信息。TLS 1.3 把大部分握手消息都加密了,包括服务器证书。这让中间人更难判断你访问的是哪个站点。
  • 取消重协商:TLS 1.2 的重协商机制曾引发过多起攻击(如 Renegotiation Attack)。TLS 1.3 干脆去掉了重协商,减少了攻击面。

安全要点: TLS 1.3 只允许使用 AEAD 密码套件,所有握手消息都加密传输,且强制前向安全性。这是目前最安全的 TLS 版本。

注意: 即使启用了 TLS 1.3,如果服务器或客户端配置了不安全的扩展(如不支持 OCSP Stapling),仍然可能带来安全风险。我曾经在一个项目中看到有人配置了 TLS 1.3 但还留着 TLS 1.2 的老密码套件作为后备——这完全破坏了所有升级带来的好处。

向后兼容性

这是很多人关心的一个问题:我升级了 TLS 1.3,旧客户端还能访问吗?答案是:TLS 1.3 协议本身并不兼容 TLS 1.2。但服务器可以同时监听两个版本。

  • 握手时版本协商:客户端在 ClientHello 中声明它支持的最高版本。服务器根据自己的配置,选择两者都支持的最高版本。如果客户端只支持 TLS 1.2,服务器会降级到 TLS 1.2。
  • 中间件兼容性:一些老旧的负载均衡器、反向代理、WAF 可能不支持 TLS 1.3。我建议在升级前先做灰度测试——先让 10% 的流量走 TLS 1.3,观察一段时间,确认没有兼容性问题再全面切换。
  • 0-RTT 的兼容性风险:0-RTT 需要客户端和服务器都支持该扩展。如果服务器不支持,会自动回退到 1-RTT 模式,不会有连接失败的问题。但要注意,0-RTT 本身有重放风险,在幂等性要求高的场景下要小心使用。

升级建议: 我个人习惯的策略是:服务器同时启用 TLS 1.2 和 TLS 1.3,优先选择 TLS 1.3;密码套件只保留 AEAD 和 ECDHE 相关的条目;配合 HSTS 和证书透明度机制,提升整体安全性。

下面这张图清晰地展示了 TLS 1.2 和 TLS 1.3 在握手流程上的关键差异:

TLS 1.2 与 TLS 1.3 握手流程对比 TLS 1.2 握手(2-RTT) ClientHello ServerHello + Certificate ServerHelloDone ClientKeyExchange ChangeCipherSpec Finished(双方互发) TLS 1.3 握手(1-RTT) ClientHello ServerHello + Certificate + Finished(合并) ClientFinished 开始传输加密数据 关键差异说明 • TLS 1.2 需要 2 轮完整往返(2-RTT)才能开始传输业务数据 • TLS 1.3 只需 1 轮(1-RTT),且支持 0-RTT 快速恢复 • TLS 1.3 将服务器证书和握手完成消息合并发送,且握手消息加密

从这张图可以很直观地看到,TLS 1.2 的握手链比较长,而 TLS 1.3 精简了两个关键消息。我个人觉得,TLS 1.3 的设计哲学就是少做没必要的事情——砍掉冗余、加密一切、强制安全。