非对称加密与密钥交换:RSA、ECDH、DHE

聊到非对称加密,很多人第一反应就是RSA。确实,RSA太经典了,经典到很多老系统到现在还在用。但我个人的经验是,选什么算法,得看场景。你想想看,一个物联网设备和一个银行核心系统,对加密的需求能一样吗?

这一章,咱们就把RSA、ECDH、DHE这几个核心算法掰开揉碎讲清楚。顺便把前向安全性这个概念彻底搞明白,再聊聊椭圆曲线怎么选——P-256还是X25519,这是个好问题。

RSA:老牌劲旅,但别滥用

RSA的原理,说白了就是大数分解的难度。给你两个大素数p和q,乘起来得到n很容易,但给你n,让你反推出p和q,那就难了。RSA的密钥对就是这么来的。

RSA既能加密也能签名,这是它的优势。但我遇到过不少项目,把RSA当万能药,什么场景都用。嗯,这里要注意:RSA不适合直接加密大量数据。它的运算速度比对称加密慢好几个数量级。实际应用中,RSA通常用来加密对称密钥,或者做数字签名。

核心要点:RSA的安全强度取决于密钥长度。目前推荐至少2048位,1024位已经被认为不安全了。我个人习惯,新系统起步就是3072位。

我曾经在一个遗留系统里看到还在用512位的RSA密钥,当时就惊了。那系统跑在公网上,相当于把保险柜的锁换成了塑料搭扣。后来我推动升级到2048位,过程虽然折腾,但安全提升是实打实的。

DHE与ECDH:密钥交换的两种思路

密钥交换要解决什么问题?简单说,就是通信双方怎么安全地商量出一个只有他俩知道的对称密钥。如果直接通过网络传密钥,中间人一抓包就泄露了。

Diffie-Hellman密钥交换协议(DH)就是干这个的。它让双方在不直接传输密钥的情况下,各自计算出一个相同的共享密钥。数学原理不复杂,但很巧妙——基于离散对数问题的难解性。

DHE和ECDH是DH的两个主流变种:

特性 DHE(Ephemeral DH) ECDH(椭圆曲线DH)
数学基础 有限域上的离散对数 椭圆曲线上的离散对数
密钥长度 2048位起步 256位即可达到同等安全
性能 较慢,计算量大 快,尤其适合移动设备
前向安全性 支持(每次会话生成临时密钥) 支持(同样使用临时密钥)
带宽占用 较大 较小

DHE的"E"代表Ephemeral(临时),意思是每次会话都生成新的临时密钥对,用完就丢。ECDH同样可以这么做,叫ECDHE。为什么要这么折腾?这就引出了前向安全性。

前向安全性:为什么它如此重要?

前向安全性(Forward Secrecy),这个概念我建议每个做安全的人都刻在脑子里。它解决的是一个很现实的问题:如果服务器的长期私钥泄露了,之前所有的通信记录会不会被解密?

如果没有前向安全性,攻击者可以先把所有加密流量都录下来,等哪天偷到了服务器私钥,再回头慢慢解密。想想看,你的聊天记录、交易数据,可能几年后被人翻出来——这太可怕了。

前向安全性的做法是:每次会话都用临时生成的密钥来加密,长期私钥只用来签名验证身份。即使长期私钥泄露,攻击者也只能伪造未来的会话,无法解密过去的记录。

我的建议:所有新系统都应该启用前向安全性。在TLS配置里,优先使用ECDHE或DHE密钥交换套件。我个人习惯,只要客户端支持,一律用ECDHE。

我曾经帮一个金融客户做安全审计,发现他们的TLS配置里全是静态RSA密钥交换,完全没有前向安全性。我跟他们解释:你们现在所有的交易记录,只要私钥一泄露,全完蛋。后来他们连夜改了配置,换成了ECDHE。

椭圆曲线选择:P-256 vs X25519

说到椭圆曲线,很多人第一反应是"选哪个?"。目前主流的选择就两个:P-256(secp256r1)和X25519(Curve25519)。

P-256是美国国家标准与技术研究院(NIST)推荐的曲线,应用最广,几乎所有TLS实现都支持。X25519是Daniel J. Bernstein设计的曲线,相对较新,但性能更好,实现也更安全。

对比维度 P-256 X25519
设计者 NIST(美国政府标准) Daniel J. Bernstein(学术界)
曲线形式 Weierstrass形式 Montgomery形式
安全强度 128位 128位
性能 较快 更快(常数时间实现更简单)
实现难度 容易出错(侧信道攻击风险) 相对安全(设计上抗侧信道)
兼容性 极广(所有平台都支持) 越来越广(主流浏览器已支持)

我个人更倾向于X25519。为什么?因为它的实现更"防呆"。P-256的Weierstrass形式在处理上有很多边界情况,实现不好容易引入漏洞。X25519的Montgomery形式设计得更干净,常数时间实现也更容易,侧信道攻击的风险低很多。

避坑指南:我曾经见过一个团队自己实现了P-256的ECDH,结果没有做点验证,导致攻击者可以通过发送不在曲线上的点来获取私钥信息。这就是典型的实现漏洞。如果当时用X25519,这种低级错误就不容易犯。

当然,如果你的系统需要跟大量老旧设备兼容,P-256还是必须支持的。我的做法是:优先协商X25519,如果客户端不支持,再回退到P-256。

知识体系总览

下面这张图把这一章的核心知识点串起来了,你可以对照着梳理一下思路:

非对称加密与密钥交换知识体系 非对称加密与密钥交换 RSA DHE ECDH/ECDHE 加密 / 签名 / 密钥传输 密钥长度:2048/3072/4096位 临时密钥对,用完即弃 基于有限域离散对数 基于椭圆曲线离散对数 256位 ≈ RSA 3072位 前向安全性(Forward Secrecy) 长期私钥泄露 → 无法解密历史会话 每次会话使用临时密钥 → 会话密钥独立,互不影响 椭圆曲线选择:P-256 vs X25519

这张图把RSA、DHE、ECDH三个分支的关系,以及前向安全性和椭圆曲线选择的位置都标清楚了。你可以看到,前向安全性是横跨DHE和ECDH的一个关键特性,而椭圆曲线选择则是ECDH落地时的具体决策点。

实际选型建议

说了这么多,到底怎么选?我给出一个实际可操作的参考:

  1. 密钥交换优先用ECDHE,曲线选X25519,回退到P-256。
  2. 签名用RSA或ECDSA,RSA密钥至少2048位,ECDSA用P-256。
  3. 如果客户端支持,完全可以用Ed25519做签名,性能更好,密钥更短。
  4. 永远启用前向安全性,在TLS配置里禁用静态RSA密钥交换套件。

一个小技巧:配置TLS时,可以用这个顺序:ECDHE-ECDSA-AES256-GCM-SHA384 优先,然后是 ECDHE-RSA-AES256-GCM-SHA384。这样既保证了前向安全性,又兼顾了兼容性。

嗯,这一章的内容就到这里。非对称加密和密钥交换是TLS安全的基础,理解透了,后面配置加密套件时心里就有底了。