TLS 握手里到底交换了什么
HTTPS = HTTP over TLS。TLS 做两件事:验证对方身份,协商出对称密钥。握手的每一步都围绕这两个目标。
身份验证:证书链
服务端发来的不是一张证书,而是一条链:站点证书 → 中间 CA → 根 CA。浏览器逐级验证签名,根证书信任来自操作系统的内置信任库。
常见故障都在这条链上:只部署了站点证书而漏了中间证书,部分客户端(老 Android、某些 Java 程序)报「证书不可信」,部分浏览器却正常(AIA 补齐机制在救场)。用 openssl s_client -connect host:443 -servername host 看 Verify return code,或者到 SSL Labs 跑一次评级。
密钥交换与加密
RSA 密钥交换(用证书公钥加密 premaster)已经淘汰——它不具备前向安全:私钥一旦泄露,历史流量全部可解。
现代 TLS 1.3 用 (EC)DHE:双方各发一个临时公钥,各自算出相同的会话密钥,私钥泄露也解不开过去的流量(前向安全)。TLS 1.3 还把握手从 2-RTT 压到 1-RTT,会话恢复可 0-RTT。
ClientHello(支持的套件 + 客户端随机数 + 密钥交换公钥)
ServerHello + 证书 + 服务器公钥 + Finished
客户端验证证书 → 双方推导会话密钥 → 应用数据
之后所有数据都是对称加密(AES-GCM / ChaCha20),非对称算法只出现在握手阶段。这也解释了「HTTPS 比 HTTP 慢很多」是个过时印象:握手一次 1-RTT,后续连接复用。
运维清单
- 只开 TLS 1.2/1.3,禁 SSLv3/TLS1.0/1.1;
- 套件优先 AEAD(AES-GCM、ChaCha20-Poly1305);
- 证书链完整、私钥权限 600;
- 上线前跑一次 SSL Labs,目标 A 以上;
- 大流量站点开启 session ticket / 0-RTT 时注意重放风险——0-RTT 数据必须设计为幂等。