2. TLS 加密原理
先聊一个基本问题:TLS 到底怎么保护你的数据?
说白了就是两层加密。一个管安全握手,一个管高效传输。
2.1 对称加密 vs 非对称加密
| 特性 | 对称加密 | 非对称加密 |
|---|---|---|
| 密钥数量 | 一把密钥,加解密都用它 | 公钥+私钥,一对儿 |
| 性能 | 极快,硬件加速友好(秒级 Gbps) | 慢,比对称慢 1000 倍以上 |
| 典型算法 | AES、ChaCha20 | RSA、ECC |
| 核心问题 | 密钥怎么安全地给到对方? | 公钥随意发,私钥自己守 |
| TLS 中的角色 | 加密传输数据(记录层) | 身份验证 + 安全传递对称密钥 |
我早期做 HTTPS 优化时踩过一个坑:以为全用 RSA 就能搞定。结果发现握手后只有对称加密在干活,RSA 只管「递钥匙」那一步。你想想看,如果每次连接都用非对称加密整个会话,服务器 CPU 直接冒烟。
TLS 的聪明之处就在这里:
- 非对称加密:握手阶段交换一个临时的对称密钥(叫 Pre-Master Secret)
- 对称加密:拿到这个临时密钥后,后续所有数据都用它加密传输
2.2 密钥交换算法
「钥匙配送」这一步,历史上出现过好几种玩法,现在主流的是 ECDHE。
RSA 密钥交换
最古老也最简单:客户端用服务器公钥加密一个随机数,发给服务器,服务器用私钥解密得到对称密钥。我在一个金融项目里见过遗留系统还在用 RSA 密钥交换,当时检查日志发现每次重连都要重新协商,而且还不支持前向安全性。
DH / DHE 密钥交换
Diffie-Hellman 让双方在不直接传递密钥的情况下,各自算出同一个共享密钥。
- 静态 DH:服务器证书里固定一个 DH 参数,前向安全性依然差(私钥泄露,历史也能破)
- 临时 DH(DHE):每次握手都用新生成的 DH 参数,即使以后私钥泄露,过去的会话仍然安全
DHE 的计算开销比较大,因为用的是大质数模幂运算。我在压测时见过 DHE 握手延迟比 RSA 高 3–5 倍。
ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)
用椭圆曲线替代大质数,安全性更高,性能却更好。我现在的项目默认只开 ECDHE,配合 X25519 曲线,握手延迟降到 3ms 以内。
| 算法 | 前向安全性 | 性能 | 当下建议 |
|---|---|---|---|
| RSA 密钥交换 | ❌ 无 | 中等 | 禁用 |
| 静态 DH | ❌ 无 | 较慢 | 禁用 |
| DHE | ✅ 有 | 慢 | 可用(兼容旧客户端) |
| ECDHE | ✅ 有 | 快 | 首选 |
2.3 密码套件组成与协商
密码套件就是一串字符串,告诉 TLS 用哪套组合拳。
举个典型例子:TLS_AES_128_GCM_SHA256
- TLS:协议版本
- AES_128_GCM:对称加密算法(AES 128位,GCM模式,带认证)
- SHA256:HMAC 哈希算法,用于消息完整性校验
如果是老版本 TLS 1.2,密码套件会更长,比如 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,这里面包含了密钥交换算法(ECDHE)和身份验证算法(RSA 签名)。
协商流程:
- 客户端发送 ClientHello,附上自己支持的密码套件列表(按优先级排序)
- 服务器从列表里选一个它也能支持的,通常选最安全且都接受的
- 服务器回复 ServerHello,带上选中的套件
- 后续握手就按这个套件定下来的算法跑
密码套件里的对称加密算法还会影响性能。我测试过 AES-GCM 和 ChaCha20-Poly1305,在移动端(没有 AES 硬件加速)ChaCha20 快 30% 以上。所以如果客户端是手机,我会优先选 ChaCha20 的套件。
这张图把 TLS 握手简化成三步,关键就是密钥交换那一步决定后续用什么对称密钥。你仔细看流程:客户端和服务器的「计算共享密钥」节点都标着绿色,说明这是握手阶段的核心,而且必须用 ECDHE 这类临时算法才能保证前向安全性。
对称加密的选型也影响整体质量。我建议:
- 服务端有 AES-NI 指令集 → 用 AES-256-GCM
- 移动端或 IoT 设备 → 用 ChaCha20-Poly1305(省电且无硬件加速也快)
- 永远别开 CBC 模式(容易 padding oracle 攻击)
嗯,以上就是 TLS 加密体系的核心骨架。你把对称/非对称、密钥交换、密码套件这三块理清了,后面看再复杂的流量处理都能快速定位问题。