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(扩展)。

  1. Extract(提取): 使用 HMAC 将输入的共享秘密(如 ECDHE 共享密钥)与盐值(salt)混合,生成固定长度的伪随机密钥(PRK)。
  2. 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 与椭圆曲线的协作关系:

TLS 1.3 密码套件与密钥交换协作流程 ClientHello 密码套件列表 + 曲线列表 ServerHello 选定套件 + 选定曲线 ECDHE 密钥交换 X25519 / P-256 共享秘密 (IKM) ECDHE 输出 HKDF-Extract PRK = HMAC(salt, IKM) HKDF-Expand 派生握手 + 应用密钥 AEAD 加密 AES-GCM / ChaCha20 TLS 1.3 安全通道建立 应用数据使用 AEAD 加密传输 说明: 密码套件决定 AEAD 算法与 HKDF 哈希函数;椭圆曲线决定 ECDHE 密钥交换参数;三者共同构成 TLS 1.3 安全基础。

3.6 常见问题与避坑

问题 1: 为什么 TLS 1.3 不再支持 RSA 密钥交换?
RSA 密钥交换不具备前向安全性(PFS),一旦私钥泄露,所有历史会话均可被解密。TLS 1.3 强制使用 ECDHE/FFDHE,确保每次会话使用临时密钥对。
问题 2: 密码套件中的 SHA-256 与 SHA-384 仅用于 HKDF,不用于证书签名验证。
证书签名验证由证书中的签名算法独立决定(如 RSA-PSS、ECDSA),与密码套件中的哈希函数无关。
问题 3: 如何选择椭圆曲线?
若客户端与服务端均支持 X25519,优先使用;否则回退到 secp256r1。避免使用 secp192r1 或 secp224r1,它们的安全强度已不满足现代要求。