术语表

TLS 握手 (TLS Handshake)

最后核实

定义

TLS 握手是 TLS 连接开始时的一组消息交换,客户端与服务器在其中协商协议版本和密码套件、验证服务器身份并派生会话密钥。

TLS 握手是应用数据受保护之前双方交换的一组消息。客户端在 ClientHello 中列出支持的版本、密码套件、密钥共享参数以及 SNI、ALPN 等扩展;服务器选定参数,发送证书链,并用私钥对握手记录签名,证明自己持有证书对应的私钥。随后双方根据密钥交换结果派生对称密钥,各自发送 Finished 消息,其中包含对整个握手过程的 MAC,任何篡改或强制降级都会被发现。

为什么重要

HTTPS 的大部分故障都出在握手阶段:证书过期或域名不匹配、缺少中间证书、双方没有共同的协议版本或套件、客户端没发 SNI 等。握手也是 TLS 主要的延迟来源:TLS 1.2 完整握手需要两个往返,TLS 1.3 只需一个,会话恢复还能进一步减少。跨境访问往返时间长,这部分差异会更明显。

例子

TLS 1.3 完整握手流程(花括号表示已加密的消息):

Client                                   Server
ClientHello (key_share, SNI, ALPN) -->
                                   <--   ServerHello (key_share)
                                         {EncryptedExtensions}
                                         {Certificate}
                                         {CertificateVerify}
                                         {Finished}
{Finished}                         -->
[Application data]                <-->   [Application data]

用 OpenSSL 观察一次真实握手,查看协商出的版本、套件和证书链:

openssl s_client -connect example.com:443 -servername example.com

常见误区

  • 流量是用证书里的公钥加密的。 现代握手中证书密钥只负责签名,真正的会话密钥来自临时密钥交换。
  • 每个请求都要握手一次。 握手按连接进行,HTTP keep-alive、HTTP/2 多路复用和会话恢复让大多数请求无需重新握手。
  • 握手失败一定是证书问题。 版本或套件不匹配、缺少 SNI、中间设备干扰同样常见。

延伸阅读