入门基础
TLS 密码套件详解:命名规则、AEAD 与推荐配置
密码套件(cipher suite)就是一次 TLS 连接所用算法组合的名字。TLS 1.2 的套件名把密钥交换、身份认证、对称加密和哈希四件事都写进去了;TLS 1.3 的套件名只管 AEAD 加密算法和密钥派生用的哈希,总共只有 5 个。截至 2026 年 11 月,稳妥的服务器配置是:TLS 1.3 用默认套件,TLS 1.2 只留少数几个 ECDHE + AES-GCM 或 ChaCha20-Poly1305 套件,其余全关。
拆开一个 TLS 1.2 套件名
TLS 1.2 套件名可以看成一句有四个空位的话,读懂它就知道连接会怎么做。
TLS _ ECDHE _ RSA _ WITH _ AES_128_GCM _ SHA256
| | | |
| | | +-- PRF 用的哈希(CBC 套件里还是 HMAC 算法)
| | +---------------- 对称加密算法、密钥长度和模式
| +----------------------------- 身份认证:证书的密钥类型
+------------------------------------- 密钥交换方式
| 位置 | 常见取值 | 决定了什么 |
|---|---|---|
| 密钥交换 | ECDHE、DHE、RSA |
共享秘密怎么产生;只有临时的 (EC)DHE 才有前向保密 |
| 身份认证 | RSA、ECDSA |
能配合哪种证书 |
| 对称加密 | AES_128_GCM、AES_256_GCM、CHACHA20_POLY1305、AES_128_CBC、3DES_EDE_CBC |
记录怎么加密 |
| 哈希 | SHA256、SHA384、SHA(即 SHA-1) |
TLS 的 PRF;CBC 套件里还用作记录 MAC |
当密钥交换和认证是同一种算法时名字会合并:TLS_RSA_WITH_AES_128_CBC_SHA 表示用 RSA 传输密钥、同时用 RSA 认证,根本没有临时密钥。
OpenSSL 有自己的一套短名字,openssl ciphers -stdname 可以两种名字对照着看:
openssl ciphers -stdname 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:AES128-SHA'
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - ECDHE-RSA-AES128-SHA TLSv1 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1
TLS_RSA_WITH_AES_128_CBC_SHA - AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
(OpenSSL 总会在最前面多打印三行 TLS 1.3 套件,这里省略了。)TLSv1、SSLv3 这一列表示该套件最早出现的协议版本,看到它基本就能判断是老套件。
TLS 1.3:只有 5 个套件
TLS 1.3 把密钥交换和身份认证从套件名里拿掉了:密钥交换走 supported_groups 和 key_share,签名走 signature_algorithms,套件只负责选 AEAD 算法和 HKDF 哈希。
| 编号 | 名称 | RFC 9846 中的地位(与 RFC 8446 相同) | OpenSSL 3.x 默认启用 |
|---|---|---|---|
| 0x1301 | TLS_AES_128_GCM_SHA256 |
必须实现 | 是 |
| 0x1302 | TLS_AES_256_GCM_SHA384 |
应当实现 | 是 |
| 0x1303 | TLS_CHACHA20_POLY1305_SHA256 |
应当实现 | 是 |
| 0x1304 | TLS_AES_128_CCM_SHA256 |
可选 | 否 |
| 0x1305 | TLS_AES_128_CCM_8_SHA256 |
可选,认证标签只有 8 字节 | 否 |
这一改动终结了 TLS 1.2 时代的组合爆炸:IANA 注册表里为各种“交换 × 签名 × 加密 × 哈希”组合登记了数百个编号。代价是光看 TLS 1.3 套件名,看不出密钥交换用的是 X25519、P-256 还是混合的 X25519MLKEM768,工具会单独报告,比如 openssl s_client -brief 里的 Negotiated TLS1.3 group: X25519MLKEM768。
2026 年 7 月发布的 TLS 1.3 修订版 RFC 9846 版本号仍是 0x0304,5 个套件也没有变;它在澄清条文的同时,把密钥交换的描述改得更通用,让 ML-KEM 这类基于 KEM 的密钥交换也能自然纳入规范。
两个 CCM 套件是给资源受限设备准备的。QUIC(RFC 9001)明确禁止 TLS_AES_128_CCM_8_SHA256,因为 8 字节标签对通用场景太短。
国密套件与 TLCP
RFC 8998 在 TLS 1.3 框架里加入了两个国密套件,适合有合规要求的国内系统。
| 编号 | 名称 | 算法 |
|---|---|---|
| 0x00C6 | TLS_SM4_GCM_SM3 |
SM4-GCM 加密,SM3 哈希 |
| 0x00C7 | TLS_SM4_CCM_SM3 |
SM4-CCM 加密,SM3 哈希 |
配合 SM2 签名证书和 curveSM2 密钥交换组使用。在 IANA 注册表里这两个套件标记为“不推荐”,意思只是 IETF 没有对它们做通用推荐,并不代表有已知弱点。
国内政务、金融等行业更常见的是另一套协议 TLCP(GB/T 38636-2020),它沿用类似 TLS 1.1/1.2 的结构,采用签名证书 + 加密证书的双证书体系,与 RFC 8998 不是一回事。标准版 Chrome、Firefox 两者都不支持,需要国密浏览器、铜锁(Tongsuo)等国密 TLS 库或专用网关。面向公众的网站通常同时部署一张国际算法证书,保证普通浏览器能访问。
套件是怎么协商出来的
客户端出价,服务器拍板。ClientHello 按偏好顺序列出客户端支持的全部套件,服务器从中选一个自己也支持的,写进 ServerHello;完全没有交集时,服务器回 handshake_failure 告警。
在 TLS 1.2 里,选定一个套件会连带其他约束:
- 选
ECDHE_ECDSA套件,服务器必须有 ECDSA 证书;选ECDHE_RSA套件,必须有 RSA 证书; - ECDHE 用的曲线来自客户端的
supported_groups,可能套件对得上、曲线却对不上; - ServerKeyExchange 的签名必须用客户端在
signature_algorithms里列出的哈希。
TLS 1.3 把这三件事拆开了:服务器分别从各自的列表里选 AEAD 套件、key_share 里的组(或用 HelloRetryRequest 要一个别的)、和证书匹配的签名算法。所以加一个后量子密钥交换组或换一张 Ed25519 证书,都不需要新的密码套件。
客户端这边的列表往往改不了:浏览器随版本内置固定列表;Java 读 java.security 文件里的 jdk.tls.disabledAlgorithms;Windows Schannel 的顺序由组策略或 PowerShell(Get-TlsCipherSuite)控制;curl、Python 继承它们链接的 TLS 库的默认值。内部系统连不上加固后的服务器时,先查清客户端用的是哪个库、哪个版本,再决定要不要动服务器。
AEAD:现代套件为什么都用它
AEAD(带关联数据的认证加密)用一个算法同时完成加密和认证,TLS 1.3 只允许 AEAD。常见的三种是 AES-GCM、ChaCha20-Poly1305(RFC 7905)和 AES-CCM。
老式 TLS 用 CBC 模式加独立的 HMAC,而且是“先 MAC 后加密”。这种结构会通过填充校验和时间差泄露信息,带来了长达十年的攻击:BEAST(2011,针对 TLS 1.0 可预测的 IV)、Lucky Thirteen(2013,CBC 填充的时间侧信道)、POODLE(2014,针对 SSL 3.0)。AEAD 没有可利用的填充预言机。ChaCha20-Poly1305 在纯软件实现下也很快,没有 AES 指令的手机和小型 ARM 设备更愿意用它。见 AEAD。
前向保密与密钥交换
只有密钥交换以 ECDHE 或 DHE 开头的套件才有前向保密。静态 RSA 密钥交换是客户端用证书公钥加密预主密钥发给服务器,日后谁拿到这把私钥,就能解密所有录下来的会话。
| 密钥交换 | 前向保密 | 现状 |
|---|---|---|
RSA(密钥传输) |
无 | 应删除;还容易受 ROBOT(2017)这类填充预言机攻击 |
DHE(有限域) |
有 | 慢,且只有 2048 位以上的组才安全;Mozilla 6.0 版已不再推荐 |
ECDHE |
有 | TLS 1.2 推荐使用 |
| TLS 1.3 的 (EC)DHE / 混合算法 | 有 | 始终使用(纯 PSK 恢复除外) |
一个容易忽略的点:会话票据是用服务器端的票据密钥加密的。如果这把密钥几个月都不换并且泄露,恢复过的会话就能被解密。要定期轮换票据密钥,做不到就关闭票据。
哪些要关、为什么
没有 AEAD、没有前向保密、或底层算法已被攻破的,都应该关掉。老服务器上还能见到的有:
| 类别 | 例子(OpenSSL 名) | 问题 |
|---|---|---|
| NULL | NULL-SHA256 |
根本不加密 |
| 匿名 | ADH-AES128-SHA |
不认证身份,中间人随便冒充 |
| 出口级 | EXP-RC4-MD5 |
故意削弱到 40/56 位;FREAK、Logjam(2015) |
| RC4 | RC4-SHA |
统计偏差;RFC 7465(2015)禁止 |
| DES / 3DES | DES-CBC3-SHA |
64 位分组;Sweet32(2016)在约 2^32 个分组(32GB)后出现碰撞 |
| CBC + SHA-1 | ECDHE-RSA-AES128-SHA |
先 MAC 后加密,填充和时间差问题 |
| 静态 RSA | AES128-GCM-SHA256 |
没有前向保密 |
| CCM_8 | TLS_AES_128_CCM_8_SHA256 |
标签太短,不适合 Web |
新版 OpenSSL 已经把最糟糕的那些排除在外:在 OpenSSL 3.6 上执行 openssl ciphers -v 'RC4' 和 openssl ciphers -v '3DES' 都会返回 “no cipher match”。RFC 9325(BCP 195,2022 年 11 月)列出了 IETF 目前推荐的 TLS 1.2 套件,和下面的 ECDHE + AEAD 列表一致。
推荐配置
公网服务器按 Mozilla 的 intermediate 档配置:TLS 1.2 和 1.3 都开,TLS 1.2 只留 6 个 ECDHE 套件。Mozilla 的指南是事实上的参考标准,截至 2026 年 11 月的最新版是 6.0,分两档:
- modern:只开 TLS 1.3,套件为
TLS_AES_128_GCM_SHA256、TLS_AES_256_GCM_SHA384、TLS_CHACHA20_POLY1305_SHA256。最老能兼容的客户端包括 Firefox 63、Chrome 70、Safari 12.1、Android 10、Java 11。 - intermediate:开 TLS 1.2 和 1.3。TLS 1.2 只允许 6 个套件:
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;密钥交换组为X25519MLKEM768、X25519、prime256v1、secp384r1;不强制服务器套件顺序。
和 5.7 版相比,6.0 删掉了 3 个 DHE 套件,加入了后量子混合组。按 intermediate 写的 Nginx 配置:
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;
ssl_prefer_server_ciphers off;
# X25519MLKEM768 需要 Nginx 链接 OpenSSL 3.5 或更高版本
ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1:secp384r1;
ssl_ciphers 只管 TLS 1.2 及以下。TLS 1.3 套件来自 OpenSSL 默认值,本来就是上面那三个;确实要改的话,Nginx 1.19.4 起可以用 ssl_conf_command Ciphersuites ...。如果 Nginx 链接的 OpenSSL 低于 3.5,要把 X25519MLKEM768 从曲线列表里去掉,否则 Nginx 会启动失败。先用 nginx -V 2>&1 | grep -i openssl 确认版本。
Apache 用协议前缀单独设置 TLS 1.3 套件:
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCipherSuite 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
SSLCipherSuite TLSv1.3 TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
SSLHonorCipherOrder off
每个 TLS 1.2 套件都出现了两次,一次给 ECDSA 证书、一次给 RSA 证书。服务器可以同时挂两种证书,按客户端能力分别下发。其他服务器的配置片段可以用 TLS 配置生成器生成。
国内常见环境的改法:
- 宝塔面板:在网站设置里打开“配置文件”,找到
ssl_protocols、ssl_ciphers两行按上面替换,保存后宝塔会自动检查并重载 Nginx。 - 阿里云、腾讯云负载均衡 / CDN:HTTPS 监听或域名的 HTTPS 配置里都有预置的 TLS 安全策略,选只含 TLS 1.2/1.3、且只有 ECDHE + GCM/ChaCha20 套件的那一档;需要兼容老客户端时再放宽,而不是在源站上改。
用 OpenSSL 查看和测试套件
openssl ciphers -v 会把套件串展开成具体套件,上线前可以先核对:
openssl ciphers -v 'ECDHE+AESGCM:ECDHE+CHACHA20' | grep TLSv1.2
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
检查线上服务器接受哪些套件,就用 s_client 一次指定一个:TLS 1.2 及以下用 -cipher,TLS 1.3 用 -ciphersuites。
# 服务器在 TLS 1.2 下还接受 CBC 套件吗?
openssl s_client -connect example.com:443 -tls1_2 -cipher ECDHE-RSA-AES128-SHA </dev/null
# TLS 1.3 下接受 ChaCha20 吗?
openssl s_client -connect example.com:443 -tls1_3 -ciphersuites TLS_CHACHA20_POLY1305_SHA256 </dev/null
返回 handshake failure 告警说明该套件已关闭。套件与协议命令手册里有逐个测试全部套件的循环脚本,密码套件查询可以解析任何 IANA 或 OpenSSL 名称。
顺序与性能
只开强套件时,顺序影响的是性能而不是安全。客户端按自己的偏好排序,没有 AES 硬件加速的手机会把 ChaCha20-Poly1305 排在前面。服务器如果强制把 AES-GCM 放第一,这些设备就用不上更快的算法,所以 Mozilla 现在建议让客户端选。OpenSSL 还有个 PrioritizeChaCha 选项:保留服务器顺序,但客户端把 ChaCha20 放第一时尊重客户端。
客户端和服务器一个共同套件都没有时握手失败,Chrome 显示 ERR_SSL_VERSION_OR_CIPHER_MISMATCH。常见原因是只开 TLS 1.3 或冷门套件的服务器碰上了老客户端,或者只会 3DES、RC4 的老设备碰上了新服务器。能改服务器列表就改列表,不要为此重新打开已被攻破的套件。
常见问题
2026 年服务器应该开哪些密码套件?
大多数公网站点:TLS 1.3 用默认套件,TLS 1.2 只保留 ECDHE + AES-GCM 或 ChaCha20-Poly1305。这就是 Mozilla 指南 6.0 的 intermediate 配置。如果客户端都支持 TLS 1.3,可以直接用只开 TLS 1.3 的 modern 配置。
AES-256 比 AES-128 更安全吗?
截至 2026 年 11 月两者都被认为是安全的。AES-128-GCM 稍快,也是 TLS 1.3 规定必须实现的套件;AES-256 安全余量更大(包括面对未来量子计算对对称密钥的影响)。常见做法是两个都开,让客户端选。
为什么 openssl ciphers 总会多出几个 TLS 1.3 套件?
OpenSSL 的 TLS 1.3 套件是单独配置的(-ciphersuites 参数或 Ciphersuites 配置项),openssl ciphers 打印时总会把它们附在前面。审查 TLS 1.2 套件串时,只看标着 TLSv1.2 的行即可。
Chrome 能访问国密 SM2 证书的网站吗?
标准版 Chrome、Firefox 不支持国密套件和 TLCP 协议。国密站点通常部署双证书:给普通浏览器一张 RSA/ECDSA 国际算法证书,给支持国密的浏览器或客户端一张 SM2 证书,由服务器按客户端能力自动选择。
资料来源
- RFC 9846: TLS 1.3(2026 年 7 月,9.1 节与附录 B.4)
- RFC 9325: Recommendations for Secure Use of TLS and DTLS(BCP 195)
- RFC 7465: Prohibiting RC4 Cipher Suites
- RFC 8998: ShangMi (SM) Cipher Suites for TLS 1.3
- Mozilla wiki: Security/Server Side TLS
- Mozilla SSL Configuration Generator
- IANA: TLS Cipher Suites 注册表
- OpenSSL 文档:openssl-ciphers