3. TLS 1.3 密码套件:支持的密码套件列表、AEAD 加密算法、HKDF 密钥派生函数、椭圆曲线选择
TLS 1.3 对密码套件进行了大幅精简与重构,移除了所有不安全的静态 RSA 密钥交换、CBC 模式加密以及非 AEAD 算法。协议强制要求所有对称加密必须使用 AEAD(Authenticated Encryption with Associated Data),密钥派生统一采用 HKDF(HMAC-based Key Derivation Function),密钥交换则限定在 有限域 Diffie-Hellman(FFDHE) 与 椭圆曲线 Diffie-Hellman(ECDHE) 之间选择。
3.1 支持的密码套件列表
TLS 1.3 仅定义了 5 个密码套件,且所有套件均采用 AEAD 加密与 HKDF 派生。相比 TLS 1.2 的数十个套件,这一精简极大降低了配置错误与降级攻击的风险。
| 密码套件标识 | AEAD 算法 | HKDF 哈希 | 密钥长度 | 备注 |
|---|---|---|---|---|
TLS_AES_128_GCM_SHA256 |
AES-128-GCM | SHA-256 | 128 bit | 强制实现,通用首选 |
TLS_AES_256_GCM_SHA384 |
AES-256-GCM | SHA-384 | 256 bit | 高安全等级,性能略低 |
TLS_CHACHA20_POLY1305_SHA256 |
ChaCha20-Poly1305 | SHA-256 | 256 bit | 软件优化,移动端首选 |
TLS_AES_128_CCM_SHA256 |
AES-128-CCM | SHA-256 | 128 bit | IoT/受限设备 |
TLS_AES_128_CCM_8_SHA256 |
AES-128-CCM-8 | SHA-256 | 128 bit | 短认证标签(8 字节) |
实践建议: 服务端应优先配置
TLS_AES_128_GCM_SHA256 以获得最佳兼容性与性能;若对侧信道攻击敏感或需要未来抗量子迁移,可启用 TLS_CHACHA20_POLY1305_SHA256 作为备选。
3.2 AEAD 加密算法
AEAD 将加密与认证合为一步,输出密文与认证标签。TLS 1.3 中 AEAD 同时保护握手记录与应用数据记录,不再单独使用 HMAC 进行消息认证。
3.2.1 AES-GCM
- 模式: Galois/Counter Mode,基于 CTR 模式 + GHASH 认证。
- 性能: 硬件 AES-NI 指令集下吞吐量极高(可达 10+ Gbps)。
- IV 构造: 固定 4 字节 salt + 8 字节 nonce(由序列号派生)。
- 安全边界: 单个密钥加密数据量不超过 239 个数据包。
3.2.2 ChaCha20-Poly1305
- 模式: ChaCha20 流加密 + Poly1305 一次性 MAC。
- 性能: 纯软件实现效率高,无硬件加速时优于 AES-GCM。
- IV 构造: 96 位 nonce(由序列号与固定常数组合)。
- 安全边界: 无已知有效攻击,抗侧信道能力较强。
3.2.3 AES-CCM
- 模式: Counter with CBC-MAC,CTR 加密 + CBC-MAC 认证。
- 性能: 通常慢于 GCM,适合资源受限设备。
- 变体: CCM-8 使用 8 字节认证标签(标准为 16 字节),用于 LoRaWAN 等极低带宽场景。
关键区别: GCM 与 ChaCha20-Poly1305 均支持并行化解密,而 CCM 的 CBC-MAC 部分为串行结构,在高速链路上可能成为瓶颈。
3.3 HKDF 密钥派生函数
TLS 1.3 使用 HKDF(RFC 5869) 作为唯一密钥派生函数。HKDF 分为两个阶段:Extract(提取) 与 Expand(扩展)。
- Extract(提取): 使用 HMAC 将输入的共享秘密(如 ECDHE 共享密钥)与盐值(salt)混合,生成固定长度的伪随机密钥(PRK)。
- Expand(扩展): 以 PRK 为根密钥,结合上下文信息(标签、长度、握手哈希),派生出多个子密钥(如客户端写密钥、服务端写密钥、IV 等)。
HKDF 使用的哈希函数由密码套件决定:SHA-256(输出 32 字节)或 SHA-384(输出 48 字节)。
// HKDF-Extract 伪代码
PRK = HMAC-Hash(salt, IKM)
// HKDF-Expand 伪代码
T(0) = ""
T(i) = HMAC-Hash(PRK, T(i-1) || info || i)
OKM = T(1) || T(2) || ... || T(n)
安全注意: 盐值(salt)在 TLS 1.3 中由握手阶段的
hello_retry_request 或 early_secret 提供。若盐值被攻击者控制,可导致派生密钥可预测。TLS 1.3 通过强制使用随机盐值(来自服务端随机数)避免此问题。
3.4 椭圆曲线选择
TLS 1.3 密钥交换仅支持 ECDHE 与 FFDHE,其中 ECDHE 是主流选择。客户端与服务端通过 supported_groups 扩展协商椭圆曲线。
3.4.1 强制与推荐曲线
| 曲线名称 | 类型 | 密钥长度 | 安全强度 | 状态 |
|---|---|---|---|---|
secp256r1 (P-256) |
素数域 Weierstrass | 256 bit | 128 bit | 强制实现 |
secp384r1 (P-384) |
素数域 Weierstrass | 384 bit | 192 bit | 强制实现 |
secp521r1 (P-521) |
素数域 Weierstrass | 521 bit | 256 bit | 推荐 |
X25519 |
Montgomery 曲线 | 256 bit | 128 bit | 推荐(性能最优) |
X448 |
Montgomery 曲线 | 448 bit | 224 bit | 推荐 |
3.4.2 曲线选择策略
- 通用场景: 优先
X25519,其常数时间实现、无侧信道漏洞、性能优于 P-256。 - 合规场景: 需要 FIPS 140-3 认证时,选择
secp256r1或secp384r1。 - 未来兼容: 可同时支持
X25519与X448,后者提供更高安全余量。
性能对比: 在相同安全强度下,X25519 的密钥生成速度约为 P-256 的 2-3 倍,且不依赖随机数生成器质量(使用固定基点标量乘法)。
3.5 密码套件与密钥交换组合流程
下图展示了 TLS 1.3 握手过程中密码套件、AEAD、HKDF 与椭圆曲线的协作关系:
3.6 常见问题与避坑
问题 1: 为什么 TLS 1.3 不再支持 RSA 密钥交换?
RSA 密钥交换不具备前向安全性(PFS),一旦私钥泄露,所有历史会话均可被解密。TLS 1.3 强制使用 ECDHE/FFDHE,确保每次会话使用临时密钥对。
RSA 密钥交换不具备前向安全性(PFS),一旦私钥泄露,所有历史会话均可被解密。TLS 1.3 强制使用 ECDHE/FFDHE,确保每次会话使用临时密钥对。
问题 2: 密码套件中的 SHA-256 与 SHA-384 仅用于 HKDF,不用于证书签名验证。
证书签名验证由证书中的签名算法独立决定(如 RSA-PSS、ECDSA),与密码套件中的哈希函数无关。
证书签名验证由证书中的签名算法独立决定(如 RSA-PSS、ECDSA),与密码套件中的哈希函数无关。
问题 3: 如何选择椭圆曲线?
若客户端与服务端均支持 X25519,优先使用;否则回退到 secp256r1。避免使用 secp192r1 或 secp224r1,它们的安全强度已不满足现代要求。
若客户端与服务端均支持 X25519,优先使用;否则回退到 secp256r1。避免使用 secp192r1 或 secp224r1,它们的安全强度已不满足现代要求。