密码套件:它到底是什么?怎么选才安全?
说到 TLS 握手,最绕不开的就是密码套件。很多人把它当黑盒,配几个字符串就完事了。我刚开始做 HTTPS 调优时也这么干,直到有一次线上告警提示「弱密码套件协商成功」——嗯,从那以后我养成了一个习惯:拿到每个套件,先拆开看它里面到底塞了哪些算法。
密码套件说白了就是一组算法的组合套餐。握手阶段双方要协商出一套都支持的套餐,然后加密通信就用这套算法。一个标准的密码套件名字像这样:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
别被这串长名字吓到。拆成四块就清楚了:密钥交换、身份认证、对称加密、消息校验。下面这张图能帮你一眼看明白它的结构。
一、密码套件的四个基本组成
每个部件都有自己的职责,缺一个都不行。我简单拆解一下:
- 密钥交换算法 —— 握手阶段双方怎么安全地生成一个共享密钥。不建议用纯 RSA,没有前向安全性。我一般只用 ECDHE 或 DHE。
- 身份认证算法 —— 服务器(有时客户端)用证书证明自己是谁。RSA 验证、ECDSA、Ed25519 都是常见选择。
- 对称加密算法 —— 真正加密通信数据。AES-GCM 是主流,ChaCha20-Poly1305 在移动端很香。
- 消息认证码(MAC) —— 保证数据没被篡改。GCM 模式自带认证 Tag,所以套件里不再单独写 MAC 算法。TLS 1.2 里有些套件会用 SHA-256 HMAC。
这几个组件组合起来,就是一个完整的密码套件。TLS 1.3 简化了这件事——它只支持五个套件,而且把密钥交换和认证算法从套件名里移到了握手扩展里处理。
二、常用密码套件列表(TLS 1.2 和 1.3)
你配置服务器时,别一股脑全列上。太多选择反而容易协商出弱套件。我个人习惯手上只留这几组:
| 套件名称 | 协议版本 | 主要特点 | 安全等级 |
|---|---|---|---|
TLS_AES_128_GCM_SHA256 |
TLS 1.3 | 128位GCM加密,SHA-256 HMAC | ⭐⭐⭐⭐⭐ 强推荐 |
TLS_AES_256_GCM_SHA384 |
TLS 1.3 | 256位GCM加密,更高安全余量 | ⭐⭐⭐⭐⭐ 强推荐 |
TLS_CHACHA20_POLY1305_SHA256 |
TLS 1.3 | 软件加密效率高,移动端首选 | ⭐⭐⭐⭐⭐ 强推荐 |
ECDHE-RSA-AES128-GCM-SHA256 |
TLS 1.2 | 前向安全,广泛兼容 | ⭐⭐⭐⭐ 推荐 |
ECDHE-ECDSA-AES128-GCM-SHA256 |
TLS 1.2 | 配合 ECC 证书性能更优 | ⭐⭐⭐⭐ 推荐 |
注意,TLS 1.3 的套件已经不写密钥交换和签名算法了。你配置的时候只需关心这五个,我通常只启用前三个,把第四个(TLS_AES_128_CCM_SHA256)和第五个(TLS_AES_128_CCM_8_SHA256)留给特殊硬件场景。
三、如何选择安全的密码套件?
选择不是拍脑袋。我总结过一套“三步走”原则,你在生产环境直接套用:
- 第一步:禁用所有不安全的算法
- RC4、3DES、CBC 模式的 AES(除非没得选)、RSA 密钥交换、DSS 签名……统统砍掉。
- 我曾经见过某厂商设备默认还支持 RC4,跑一次合规扫描全红。
- 第二步:优先选择前向安全的密钥交换
- ECDHE 和 DHE 都能保证私钥泄露后历史会话不被破解。切记别漏了 ECDHE。
- 第三步:平衡性能和兼容性
- 大部分人用 TLS 1.3 套件就够了。如果必须兼容老客户端,保留一两个 TLS 1.2 强套件。
ECDHE-RSA-AES128-GCM-SHA256是出了名的“万能油”,性能好,兼容广。
💡 一个稳妥的 Nginx 配置示例(TLS 1.2 + 1.3):
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
这个列表只用了 ECDHE/DHE + GCM/ChaCha20,没有 CBC,没有 RSA 密钥交换。我自己线上就这么跑的,扫描结果全部 A+。
🔧 一个小技巧: 在 OpenSSL 里可以用 openssl ciphers -V 'EECDH+AESGCM:EDH+AESGCM' 快速列出你允许的套件详细信息,包括 IANA 编号。我每次调整配置前都会跑一遍这个命令确认。
⚠️ 避坑指南: 我曾经因为贪快,在内部系统里留下了一个 AES128-CBC-SHA 套件。后来安全扫描报出 Lucky13 攻击风险——幸好只是内部测试环境。从那以后我养成了用 ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!DSS:!kRSA 这种全排除式写法兜底。
四、密码套件选择决策思路
最后帮你捋一下思考路径。当你面对一大串密码套件名时,按这个顺序判断:
- 版本:支持 TLS 1.3 优先用 1.3 套件。
- 密钥交换:有没有 ECDHE?没有就降级。
- 加密算法:是不是 AEAD(GCM 或 ChaCha20)?CBC 模式尽量不用。
- MAC 强度:SHA-256 起步,SHA-384 更好。
- 兼容性:客户端能力不足时,才考虑降级到 TLS 1.2 强套件。
嗯,这套思路我在好几个公司推行过,从电商到金融都适用。只要把这几层卡住,密码套件基本不会成为安全短板。