4. 非对称加密与密钥交换

在TLS握手中,非对称加密并不用来直接加密应用数据,它承担的是“身份认证”和“密钥协商”两类任务。理解这一点,是理解RSA与ECDHE差异的起点。RSA密钥交换的核心思路是:客户端生成预主密钥,用服务器证书中的RSA公钥加密后发送,只有持有RSA私钥的服务器能解密。ECDHE则完全不同,双方各自生成临时椭圆曲线密钥对,交换公钥后通过ECDH运算得到共享秘密,服务器私钥只用于签名认证,不参与密钥计算。

这个差异直接决定了“前向保密”能力。前向保密(Forward Secrecy,FS)指长期私钥泄露后,攻击者仍无法解密此前录制的历史会话。RSA密钥交换不具备前向保密:如果服务器RSA私钥被泄露,攻击者可以解密所有用该私钥保护过的预主密钥,进而还原历史会话密钥。ECDHE的每次握手都生成临时密钥对,会话结束后私钥即被丢弃,长期私钥只用于签名,因此即使证书私钥泄露,也无法还原过去的会话密钥。

RSA 密钥交换 vs ECDHE 密钥交换:前向保密差异 RSA 密钥交换(无前向保密) 客户端 服务器 ① 请求证书 ② 返回 RSA 公钥证书 ③ 客户端生成预主密钥 PMS 用服务器 RSA 公钥加密 PMS → 发送 PMS 被长期私钥保护 ④ 服务器用 RSA 私钥解密 PMS 双方由 PMS 推导会话密钥 ⚠ 长期私钥泄露 → 历史会话全部可解密 攻击者录制密文后,用泄露私钥解密 PMS → 还原主密钥 → 还原会话密钥 不具备前向保密 ECDHE 密钥交换(前向保密) 客户端 服务器 ① 请求证书 ② 返回证书 + 签名 ③ 双方各自生成临时 ECDHE 密钥对 交换临时公钥,各自计算共享秘密 长期私钥仅用于签名认证 ④ 临时私钥用完即弃 会话密钥由临时共享秘密推导 ✓ 长期私钥泄露 → 历史会话仍安全 攻击者无法从签名私钥还原临时私钥 → 无法计算共享秘密 → 无法解密 具备前向保密

在TLS 1.2中,密钥交换算法由密码套件名称决定。例如 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 表示:ECDHE用于密钥交换,RSA用于身份认证,AES-128-GCM用于对称加密,SHA256用于PRF。而 TLS_RSA_WITH_AES_128_GCM_SHA256 则是RSA同时承担密钥交换和认证,不具备前向保密。TLS 1.3进一步简化了设计,只保留(EC)DHE类密钥交换,彻底移除了RSA密钥交换,并将密钥交换与认证分离得更加清晰。

工程实践中,选择ECDHE还是RSA密钥交换,需要权衡多个因素。性能方面,ECDHE在握手阶段增加了椭圆曲线点乘运算,但现代CPU和优化库(如OpenSSL的EC优化、汇编实现)已将其开销控制在可接受范围。以NIST P-256曲线为例,一次ECDHE密钥生成加共享秘密计算通常在百微秒级别,相比RSA-2048解密(约1-2毫秒)反而更快。但ECDHE的证书签名验证仍需RSA或ECDSA运算,这部分开销不可忽略。

兼容性方面,老旧客户端可能不支持ECDHE,此时服务器需要保留RSA密钥交换套件作为回退。但现代浏览器和主流操作系统均已支持ECDHE,且TLS 1.3强制要求前向保密,因此新部署的服务应优先启用ECDHE并逐步淘汰纯RSA套件。配置时可通过密码套件优先级控制,例如在Nginx中设置 ssl_ciphers 'ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM',将ECDHE套件置于前面。

曲线选择也是工程取舍的一部分。P-256兼容性最好,P-384安全性更高但性能略低,X25519在性能和安全性之间取得了良好平衡,且实现更简洁、更不易出错。TLS 1.3推荐X25519为首选。实际部署中可同时配置多条曲线,由客户端和服务端协商选择。

实践建议:新服务优先配置TLS 1.3 + X25519/P-256 + ECDHE套件;若需兼容老旧客户端,保留少量RSA套件但置于最低优先级;定期使用 openssl s_client -connect host:443 -cipher 'ECDHE' 验证前向保密是否生效。

最后需要明确:前向保密保护的是“历史会话”,而非“当前会话”。如果攻击者同时获取了当前会话的临时私钥和长期私钥,当前会话仍可能被解密。因此,临时私钥的生成质量、随机数源的安全性、以及密钥材料的及时销毁,都是前向保密能否真正落地的关键。工程上应确保使用操作系统提供的安全随机数(如 /dev/urandom 或 getrandom()),并避免在内存中长时间保留临时私钥。