HTTPS 握手:浏览器和服务器刚连上时到底在聊什么

TL;DR

TLS 1.3 握手用证书确认身份,用密钥协商建立共享秘密,再用 Finished 消息确认双方看到的是同一条会话。本文按消息顺序拆解 1-RTT 握手、前向保密、0-RTT 重放风险,以及 HTTPS 的保护边界。

TLS 1.3 握手用证书确认身份,用密钥协商建立共享秘密,再用 Finished 消息确认双方看到的是同一条会话。本文按消息顺序拆解 1-RTT 握手、前向保密、0-RTT 重放风险,以及 HTTPS 的保护边界。

HTTPS 握手:浏览器和服务器刚连上时到底在聊什么

浏览器地址栏出现 HTTPS 后,页面并不是立刻开始传输业务数据。客户端和服务器要先完成一场 TLS 握手:确认服务器身份、协商密码套件、建立共享密钥,并证明双方都拥有正确的握手状态。TLS 1.3 规范把这套流程、密钥派生和消息保护写得非常明确。RFC 8446

很多人会把 HTTPS 简化成“用公钥加密网页”。更准确的说法是:公钥密码主要用于身份认证和建立密钥,真正的大量业务数据通常使用对称加密,因为对称加密更适合高吞吐的数据传输。

TLS 握手要解决三个问题

1. 我连到的是谁

服务器发送证书链。证书把域名、公钥和证书颁发机构的签名联系起来。浏览器根据信任根、域名匹配、有效期、用途和撤销策略检查证书。如果证书验证失败,浏览器会阻止或强烈警告,而不是把任意公钥都当成服务器身份。

2. 双方用什么算法

客户端在 ClientHello 中带上支持的版本、密码套件、随机数和密钥交换信息。服务器在 ServerHello 中选择参数。TLS 1.3 的密码套件主要描述对称加密和哈希组合,密钥交换与认证算法被拆开协商,让协议结构更清晰。

3. 如何得到同一把会话密钥

现代 TLS 通常使用基于椭圆曲线的临时 Diffie–Hellman 密钥交换。双方交换公开参数,各自用私密参数计算出相同的共享秘密,但旁观者无法仅凭公开信息得到它。随后,TLS 的密钥派生函数把握手上下文、共享秘密和随机值变成不同用途的握手密钥与应用数据密钥。

TLS 1.3 的消息顺序

可以把一次完整握手理解为:

  1. 客户端发送 ClientHello,提出能力并带上临时公钥。
  2. 服务器返回 ServerHello,选择参数并带上自己的临时公钥。
  3. 双方据此派生握手密钥,后续很多握手消息开始被加密。
  4. 服务器发送证书、CertificateVerifyFinished,证明自己拥有证书对应的私钥,并确认握手摘要。
  5. 客户端验证服务器后发送自己的 Finished
  6. 双方切换到应用数据密钥,开始传输 HTTP 内容。

“Finished” 为什么重要

如果只有证书和密钥交换,攻击者仍可能篡改握手参数,让双方对“到底协商了什么”产生不同理解。Finished 消息包含对前面握手消息的认证结果,双方验证它,就能确认握手 transcript 没有被悄悄改写。

这也是 TLS 的一个关键思想:不仅要加密后续数据,还要认证建立加密通道的整个过程。认证失败时,不能继续使用一条看似加密、实际参数被篡改的连接。

为什么 TLS 1.3 更快

完整 TLS 1.3 握手通常可以在一次往返中完成,减少了旧版本里的一些协商步骤。连接复用和会话恢复还能进一步降低后续访问的握手成本。

但“0-RTT 更快”需要谨慎。TLS 1.3 的 0-RTT 允许恢复会话的客户端更早发送数据,可是这类早期数据可能被攻击者重放。适合 0-RTT 的应是幂等、可安全重复的请求;支付、下单和修改状态的操作不能因为追求少一次往返就直接放开。

TLS 保护了什么,没保护什么

TLS 主要保护客户端与终止 TLS 的服务器之间的数据机密性、完整性和服务器身份。它不自动保证:

  • 服务器内部不会泄露数据。
  • 业务接口没有越权和重放漏洞。
  • DNS 一定把你带到正确的 IP。
  • 页面里的第三方脚本不会读取敏感信息。
  • 用户连接的域名本身一定值得信任。

如果前面还有 CDN、反向代理或服务网格,TLS 可能在多个位置终止。每个终止点都是一个需要保护、审计和控制访问的信任边界。

一句话带走

HTTPS 的“锁”不是一次简单的公钥加密,而是一套先认证身份、再协商共享秘密、最后切换高效对称加密的协议流程。真正值得记住的是:证书回答“你是谁”,密钥交换回答“我们如何共享秘密”,Finished 回答“刚才的协商有没有被改过”。

延伸阅读

KEEP READING