4. TLS 1.3 密钥交换:ECDHE 密钥交换原理、前向安全性、密钥协商过程、临时密钥生成

4.1 ECDHE 密钥交换原理

ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)是 TLS 1.3 中唯一的密钥交换算法(传统 RSA 密钥交换已被移除)。它结合了椭圆曲线密码学(ECC)的高效性与临时密钥的“一次一密”特性,是 TLS 1.3 安全性的核心支柱。

ECDHE 基于椭圆曲线上的离散对数难题(ECDLP):给定基点 G 和公钥 Q = d·G,求私钥 d 在计算上不可行。双方通过交换临时公钥,各自计算共享秘密,而窃听者无法从公开信道中恢复该秘密。

核心优势: 相比传统 DHE,ECDHE 在同等安全强度下密钥长度更短(256 位 ECC 约等于 3072 位 RSA/DH),计算速度更快,带宽占用更低。

4.2 前向安全性(Perfect Forward Secrecy, PFS)

前向安全性是 TLS 1.3 的强制性要求。其核心思想是:即使服务器长期私钥泄露,也无法解密之前记录的会话流量。

特性 RSA 密钥交换(TLS 1.2 及之前) ECDHE 密钥交换(TLS 1.3)
会话密钥生成方式 客户端生成 Pre-Master Secret,用服务器 RSA 公钥加密传输 双方通过 ECDHE 临时密钥对独立计算共享秘密
长期私钥作用 用于解密 Pre-Master Secret,直接暴露会话密钥 仅用于签名认证,不参与密钥派生
长期私钥泄露后果 所有历史会话均可被解密 历史会话安全,无法解密
前向安全性 ❌ 不支持 ✅ 强制支持
关键理解: 在 ECDHE 中,服务器长期私钥只用于对 ECDHE 临时公钥进行数字签名(证明该公钥确实来自该服务器),而从不参与会话密钥的计算。因此,即使攻击者获取了服务器私钥,也只能伪造身份,无法解密已记录的会话流量。

4.3 密钥协商过程(TLS 1.3 完整握手)

TLS 1.3 将握手压缩为 1-RTT(往返时间),密钥协商与证书认证并行进行。以下是完整的 ECDHE 密钥协商流程:

  1. ClientHello: 客户端发送支持的密码套件列表、随机数 client_random,以及 ECDHE 临时公钥 client_share(包含曲线类型和公钥值)。
  2. ServerHello: 服务器选择密码套件,发送随机数 server_random,以及 ECDHE 临时公钥 server_share。
  3. EncryptedExtensions + Certificate + CertificateVerify: 服务器发送证书链,并用长期私钥对握手消息签名(包含双方的 ECDHE 公钥),证明身份。
  4. 密钥派生: 双方使用 ECDHE 计算共享秘密 shared_secret,再通过 HKDF(HMAC-based Key Derivation Function)派生出会话密钥。
  5. Finished: 双方发送握手消息的 MAC,验证握手完整性。
TLS 1.3 ECDHE 密钥协商流程(1-RTT) 客户端 服务器 ① ClientHello client_random + client_share (ECDHE 公钥) ② ServerHello server_random + server_share (ECDHE 公钥) ③ Certificate + CertificateVerify 服务器证书 + 对握手消息的数字签名 计算共享秘密 ECDHE(server_share, client_priv) 计算共享秘密 ECDHE(client_share, server_priv) HKDF 派生会话密钥 HKDF 派生会话密钥 ④ Finished(握手完整性校验)

4.4 临时密钥生成

临时密钥(Ephemeral Key)是 ECDHE 实现前向安全性的关键。每次 TLS 握手都会生成全新的临时密钥对,握手结束后立即销毁私钥。

4.4.1 密钥生成步骤

  1. 选择曲线: TLS 1.3 强制支持 secp256r1(P-256)和 X25519(Curve25519)。推荐优先使用 X25519,因其实现更安全、性能更优。
  2. 生成临时密钥对: 使用安全的随机数生成器(CSPRNG)产生私钥 d(256 位随机数),计算公钥 Q = d·G。
  3. 编码与传输: 公钥以未压缩格式(x,y 坐标)或 X25519 的 32 字节标量形式编码,放入 KeyShareEntry 结构中传输。
  4. 计算共享秘密: 收到对方公钥后,使用自己的私钥执行标量乘法:shared_secret = d_own · Q_peer。
安全实践: 临时私钥必须使用操作系统提供的安全随机数生成器(如 Linux 的 /dev/urandom),且使用后应立即从内存中擦除(zeroize),防止侧信道攻击或内存转储泄露。

4.4.2 密钥派生(HKDF)

ECDHE 计算出的共享秘密是一个椭圆曲线上的点,不能直接用作对称密钥。TLS 1.3 使用 HKDF(RFC 5869)进行密钥派生:

// 伪代码:TLS 1.3 密钥派生流程
// 输入:shared_secret (ECDHE 输出), client_random, server_random
// 输出:handshake_traffic_secret, application_traffic_secret

// 第1步:提取(Extract)
early_secret = HKDF-Extract(salt=0, ikm=PSK)  // 无 PSK 时 salt=0
handshake_secret = HKDF-Extract(salt=early_secret, ikm=shared_secret)

// 第2步:扩展(Expand)
client_handshake_traffic_secret = HKDF-Expand-Label(
    handshake_secret, "c hs traffic", client_random + server_random, 32)
server_handshake_traffic_secret = HKDF-Expand-Label(
    handshake_secret, "s hs traffic", client_random + server_random, 32)

// 第3步:派生应用层密钥
master_secret = HKDF-Extract(salt=handshake_secret, ikm=0)
client_application_traffic_secret = HKDF-Expand-Label(
    master_secret, "c ap traffic", client_random + server_random, 32)
server_application_traffic_secret = HKDF-Expand-Label(
    master_secret, "s ap traffic", client_random + server_random, 32)

4.4.3 曲线对比

曲线 密钥长度 安全强度 性能 TLS 1.3 支持
secp256r1 (P-256) 256 位 128 位 中等(需验证点是否在曲线上) ✅ 强制
X25519 (Curve25519) 256 位 128 位 高(常数时间实现,无专利限制) ✅ 推荐
secp384r1 (P-384) 384 位 192 位 较低 ✅ 可选
总结: ECDHE 通过临时密钥对 + 椭圆曲线密码学,实现了 TLS 1.3 的强制前向安全性。每次握手独立生成密钥,长期私钥仅用于签名认证,确保即使未来私钥泄露,历史会话依然安全。HKDF 的提取-扩展结构保证了密钥的随机性和独立性,是 TLS 1.3 安全架构的基石。