HTTPS 协议基础:HTTP over TLS、加密流程、握手过程、TLS 记录层协议
做负载均衡这么多年,我见过太多团队把 SSL Offloading 当成一个开关来用。“打开,性能好了,然后出 bug 了。” 为什么?我觉得根本原因在于,很多人对 HTTPS 底层跑的东西只有一个模糊的概念。这一节,我想带着你把 HTTPS 这个盒子真正打开看看。
说白了,HTTPS 就是 HTTP 外面套了一层 TLS。HTTP 本身是明文,数据包在链路上随便抓一下就看得清清楚楚。TLS 把这层通道加密了,你能抓到包,但解不开。就这么简单的一个逻辑,但实现起来细节相当多。
一句话总结:HTTPS = HTTP + TLS。TLS 负责加密、认证、完整性校验,HTTP 负责业务数据的格式。
1.1 加密流程:两把钥匙的故事
你想想看,如果两个人要在一个公共通道上悄悄说话,怎么做?最简单的方法是两个人先用一种只有对方知道的语言聊天。对应到 HTTPS,就是双方先约定一个“对称密钥”,之后所有数据都用这个密钥加密。
但问题来了:怎么在第一次见面的时候,安全地把这个密钥告诉对方?直接发出去,中间有人截获怎么办?
这就引出了我们说的“非对称加密”。服务器先把自己的公钥广播出去,客户端用这个公钥加密一个随机数(也就是后续的对称密钥),发给服务器。服务器用自己的私钥解开,拿到这个随机数。整个过程,只有客户端和服务器知道这个随机数。
我在项目中遇到过一种情况:某团队为了让性能更高,直接调整了密钥协商的参数,把 DH 交换的素数位数降到了 1024 位。结果安全扫描没过,被勒令整改。嗯,这里要注意,性能和安全很多时候是个 trade-off,但有些底线不能碰。
| 加密类型 | 特点 | 典型算法 | 在握手中的作用 |
|---|---|---|---|
| 对称加密 | 加密解密用同一个密钥;速度快 | AES, ChaCha20 | 加密真正的 HTTP 数据 |
| 非对称加密 | 公钥加密,私钥解密;速度慢 | RSA, ECDHE | 安全地交换对称密钥 |
我的建议:生产环境优先用 ECDHE(椭圆曲线 Diffie-Hellman)来交换密钥。它支持前向安全性,就算服务器私钥泄露了,历史会话的数据也无法被解密。RSA 密钥交换正在被逐步弃用。
1.2 握手过程:来回四次,建立信任
HTTPS 的握手,我习惯把它拆成四个阶段来看。别被 RFC 那么多状态吓到,核心就这几个步骤。我记得刚做运维那会儿,每次看着 Wireshark 里密密麻麻的 Client Hello、Server Hello,心里就发怵。后来拆开看,其实很清晰。
- Client Hello:客户端告诉服务器,我支持哪些 TLS 版本、加密套件、扩展。同时带上一个随机数。
- Server Hello + 证书:服务器选好双方都支持的版本和套件,发回自己的随机数。然后亮出数字证书,证明自己的身份。
- 密钥协商:客户端验证证书合法性,然后用服务器的公钥加密一个“预主密钥”发过去。双方各自用这个预主密钥和前面的随机数,计算出最终的对称密钥。
- Finished 消息:双方都发一条用对称密钥加密的消息,确认从此开始所有通信都是加密的。
你可能会问:证书验证是在哪一步?就在第三步。客户端拿到证书后,会校验证书是否由可信 CA 签发、域名是否匹配、是否过期。有一年我排查一个 HTTPS 报错,发现是客户的内部 CA 根证书没在服务器上导入。这个坑我踩过,印象特别深。
下面这张图,是我自己整理的一个简化握手流程。你看一眼,基本上就能把整个过程串起来了。
1.3 TLS 记录层协议:数据是怎么打包的
握手完成之后,数据怎么传?TLS 把数据切成一段一段的,每一段称为一个“记录”。每个记录有一个头部,包含内容类型、版本、长度,后面跟着加密后的负载和 MAC(消息认证码)。
我最初觉得记录层就是个打包格式,没什么好看的。直到有一次排查一个 HTTPS 性能问题,发现某个大文件传输时,客户端一直发很小的记录,导致 TLS 协议开销占比特别高。为什么?因为每个记录都要单独加密、追加 MAC。记录切得越小,开销占比越大。
记录层的作用包括:
- 分片:将应用层数据(HTTP 报文)切成 16KB 以内的块。
- 压缩:标准中可选,但出于安全考虑,现在的实现基本都不做压缩了。
- 加密 + MAC:要么先加密再计算 MAC(TLS 1.2 之前的 CBC 模式),要么用 AEAD 一步到位(AES-GCM、ChaCha20-Poly1305)。
- 记录头部:5 字节,告诉你这包是 alert、handshake 还是 application data。
避坑指南:我曾经在一次压测中发现,某些老旧的负载均衡设备不支持 TLS 1.3 的 0-RTT 模式。导致开启后,客户端重放攻击防护有问题。如果你做 SSL Offloading,务必确认你的 ADC(应用交付控制器)支持 TLS 1.3 的完整语义,包括 0-RTT 的重放保护。
OK,到这里,HTTPS 最基础的三块东西——加密干什么、握手怎么握、数据怎么装——你应该心里有数了。这些概念在后面对接负载均衡的 SSL Offloading 时,会反复用到。比如 Offloading 到底卸掉的是什么?卸掉的就是握手和记录层加密的 CPU 负担。但有些安全要求高的情况,你又不能全卸。怎么权衡?后面会一步步展开说。