TLS 握手(TLS 1.3 主线)
以 TLS 1.3 为主线串联 ClientHello/ServerHello、(EC)DHE key agreement、证书与 CertificateVerify、HKDF key schedule、Finished 和 AEAD record protection,并把 TLS 1.2 的 RSA key transport 降为历史对照。
[!info] related notes
- 所属 MOC: HTTP 与前端网络请求 MOC
- HTTPS: HTTPS
- PKI: PKI
- Key Schedule: TLS 1.3 Key Schedule
- AEAD: AEAD
- 断开: TLS/HTTPS 连接关闭
- 排障: TLS 握手失败排查
TLS 握手(TLS 1.3 主线)
为什么不再背“HTTPS 四次握手”
“HTTPS 四次握手”不是协议标准术语。
TLS message:
- 可能被合并;
- 可能跨多个 record;
- TLS 1.2 与 TLS 1.3 流程不同;
- resumption / 0-RTT / client auth 会改变流程。
因此更稳定的学习方式是:
按握手阶段和安全目标理解,而不是死背“第几次握手”。
前置关系
HTTPS 典型 TCP 场景:
TCP connection established
→ TLS handshake
→ HTTP over protected channel
HTTP/3 则运行在 QUIC 上,TLS 1.3 与 QUIC handshake 深度集成,不存在同样的 TCP 前置过程。
TLS 1.3 主线
一个简化的新连接流程:
ClientHello
→ ServerHello
→ EncryptedExtensions
→ Certificate
→ CertificateVerify
→ Finished
→ client Finished
→ Application Data
实际消息会因:
- PSK;
- resumption;
- client certificate;
- HelloRetryRequest;
等情况变化。
1. ClientHello
客户端发送:
- supported_versions;
- cipher suites;
- key_share;
- supported groups;
- SNI;
- ALPN;
- signature algorithms;
- 可能的 PSK/resumption 信息。
TLS 1.3 中,客户端通常已经在 ClientHello 提供 ephemeral key share。
2. ServerHello
服务器选择:
- TLS version;
- cipher suite;
- key share/group。
双方结合 ephemeral (EC)DHE material,得到 shared secret。
从这一点开始,就可以进入 TLS 1.3 的 HKDF key schedule。
3. Handshake Traffic Secrets
(EC)DHE / PSK
→ HKDF
→ handshake traffic secrets
ServerHello 后的大部分后续握手消息已经处在加密保护下。
这和 TLS 1.2 大量握手元数据明文暴露的模型不同。
4. Certificate
服务器发送 certificate chain,给客户端提供:
- server public key;
- DNS/identity binding;
- issuer chain。
客户端检查:
- trust chain;
- SAN / hostname;
- validity;
- key usage;
- policy。
详见 PKI。
5. CertificateVerify
服务器用 certificate 对应 private key 对 handshake transcript 做数字签名。
它的作用是证明:
当前握手确实由控制该 certificate private key 的服务器参与。
注意:
certificate private key
≠ ECDHE ephemeral private key
≠ application traffic key
这三类 key 的职责不同。
6. Finished
Finished 使用由 key schedule 派生的 finished key,对 handshake transcript 做认证。
它证明:
- 双方导出了匹配的 secrets;
- handshake transcript 没被无声修改。
客户端验证 server Finished 后,再发送自己的 Finished。
7. Application Traffic Keys
握手继续派生:
- client application traffic secret;
- server application traffic secret。
再生成各方向:
- AEAD key;
- IV。
后续 HTTP data 通过 AEAD record protection 发送。
TLS 1.3 cipher suites 只包含:
- AEAD;
- Hash。
不再把 authentication / key exchange 也塞进 cipher suite 名字里。
TLS 1.3 为什么不需要 RSA 加密 Premaster Secret
旧 TLS 1.2 可以存在 RSA key transport:
client generates premaster secret
→ encrypt with server RSA public key
→ server decrypts with private key
这种流程:
- 不提供 Forward Secrecy;
- TLS 1.3 已移除。
现代主线是:
(EC)DHE
→ shared secret
→ HKDF key schedule
certificate key 主要承担 authentication/signature,而不是加密 premaster secret。
TLS 1.2 仍要理解什么
TLS 1.2 仍大量存在于历史资料和兼容系统。
需要知道:
- cipher suite 组合更复杂;
- key exchange 可以是 ECDHE、DHE、历史 RSA 等;
- ChangeCipherSpec 在真实状态机中有更明确角色;
- handshake encryption 边界与 TLS 1.3 不同。
但不要再把它作为“HTTPS 永远固定流程”。
Session Resumption
TLS 1.3 可使用之前连接派生的 PSK 做 resumption。
优点:
- 减少握手成本;
- 可以支持 0-RTT early data。
风险:
- 0-RTT 可能被 replay。
所以有副作用的业务请求仍必须具备 replay-safe design。
Forward Secrecy
ephemeral (EC)DHE 意味着每个 connection 使用临时 key agreement material。
因此:
长期 certificate signing key 日后泄漏
≠ 自动恢复历史 session traffic key
这就是 Forward Secrecy 的核心收益之一。
一张职责图
DNS / TCP or QUIC
→ ClientHello / ServerHello
→ ECDHE / PSK establish secret
→ HKDF derive traffic secrets
→ Certificate + CertificateVerify authenticate server
→ Finished authenticate transcript
→ AEAD protect application records
→ HTTP semantics
常见误区
TLS 1.3 仍然用服务器 RSA 公钥加密 session key
错误。TLS 1.3 不再支持静态 RSA key exchange。
Certificate 中有 public key,所以它就是 session encryption key
错误。certificate key 主要参与身份认证;traffic keys 从 key schedule 派生。
Finished 就是最后发送一个 Hash
不准确。Finished 使用派生 finished key 对 transcript 做认证。
HTTPS 一定是 TCP 三次握手 + TLS 四次握手
HTTP/3/QUIC 已经打破这种固定分层描述。
学习检查
- 为什么“HTTPS 四次握手”不是稳定协议模型?
- TLS 1.3 ClientHello 为什么通常直接携带 key share?
- Certificate 与 CertificateVerify 分别解决什么问题?
- certificate private key、ECDHE ephemeral key、traffic key 有什么差异?
- Finished message 证明了什么?
- TLS 1.3 为什么移除 RSA key transport?
- TLS 1.3 cipher suite 为什么只需要描述 AEAD + hash?
- HTTP/3 为什么不能简单套“先 TCP,再 TLS”的流程?