TLS 1.3 握手快在哪
TLS 1.3 把完整握手压缩到一次往返:客户端在 ClientHello 里直接带上 key_share(预生成的密钥交换公钥),服务器回一条 ServerHello 就能推出会话密钥,此后所有握手消息都在加密通道里传输。会话恢复还能做到 0-RTT,在第一个包里就发应用数据,代价是这部分数据不具前向保密且可被重放。
基本信息
| 往返次数 | 首次连接 1-RTT,会话恢复可 0-RTT |
|---|---|
| 关键扩展 | supported_versions、key_share、pre_shared_key、early_data |
| 加密范围 | ServerHello 之后的所有握手消息均加密 |
| 规范 | RFC 8446 |
| 支持情况 | 取决于 OpenSSL/BoringSSL/NSS 版本,服务端与客户端都要支持 |
1-RTT 骨架
1-RTT 骨架
Client -> Server: ClientHello + key_share (+ early_data)
Server -> Client: ServerHello + key_share
{EncryptedExtensions, Certificate, CertificateVerify, Finished}
Client -> Server: {Finished}
# 花括号内的消息在握手密钥下加密,中间设备只能看到版本与长度观察握手
观察握手
openssl s_client -connect example.com:443 -tls1_3 -msg </dev/null 2>&1 | head -20
openssl s_client -connect example.com:443 -brief </dev/null # 快速确认是否协商到 1.3
tcpdump -nn -s0 -A 'tcp port 443' -c 20 | grep -i key_share # 在 ClientHello 里找 key_share与 1.2 的关键差异
| 项目 | TLS 1.3 | TLS 1.2 |
|---|---|---|
| 往返 | 1-RTT,恢复可 0-RTT | 2-RTT |
| 密钥交换 | 只允许 (EC)DHE,参数随 Hello 一起发 | 可用 RSA 密钥传输,无前向保密 |
| 加密范围 | ServerHello 之后全部加密 | 证书等消息明文可见 |
| 密码套件 | 只保留 AEAD,去掉 CBC 与静态 RSA | 包含 CBC 与静态 RSA 套件 |
| 重协商 | 移除,改用密钥更新 | 支持重新协商 |
典型使用场景
- 移动端弱网:少一个往返对首包延迟改善明显
- 高并发网关:1.3 的握手开销与 CPU 占用低于 1.2
- 会话恢复频繁的站点,用 0-RTT 让回头客直接发数据
- 需要隐藏证书信息的场景:1.3 让中间设备看不到证书内容
- 合规审计:确认服务端已禁用弱套件与旧版本
0-RTT 数据可被复制重放且没有前向保密;只应对幂等请求开放,登录、下单等写操作必须在完整握手后发送。
服务端开启检查
- 确认软件版本支持 1.3:OpenSSL 1.1.1 起、nginx 1.13.0 起
- ssl_protocols 同时保留 TLSv1.2 与 TLSv1.3,避免老客户端整体不可用
- 1.2 的套件用 ssl_ciphers 配,1.3 的套件用 ssl_ciphersuites 配,两者互不影响
- 按需开启会话票据以支持快速恢复,同时评估票据密钥的轮换与保护