常见签名算法:RSA、ECDSA、Ed25519
做签名验签这么多年,我发现在选算法这块,很多人容易走弯路。直接说结论:没有万能的算法,只有适不适合的场景。今天咱们就聊聊三种最常见的——RSA、ECDSA 和 Ed25519。
你可能会问:这么多算法,我该选哪个?嗯,别急,我们从原理到实战,一个一个拆开看。
RSA:老大哥,稳但慢
RSA 是最成熟的公钥算法,基于大整数分解难题。简单说就是:两个大质数相乘容易,但从乘积反推质数极难。
我个人习惯把 RSA 比作「保险柜」——钥匙越长越安全,但开锁也越费劲。举个例子:
核心参数
- 密钥长度:2048 位是当前最低要求,4096 位更安全
- 签名速度:慢(尤其私钥操作)
- 验签速度:快(公钥操作)
- 签名长度:固定等于密钥长度(如 256 字节)
我在项目中遇到过一个问题:某支付系统用 RSA 做签名,业务量涨上去后,HSM 的 CPU 直接飙到 90%。后来一查,签名时私钥指数太大,每次计算都是大数模幂,硬件扛不住了。
避坑指南
我曾经见过有人把 RSA 私钥指数(d)设置得特别大,以为越随机越安全。其实公钥指数(e)用 65537 就够了,私钥指数过大只会拖慢性能。
ECDSA:椭圆曲线,短而快
ECDSA 基于椭圆曲线离散对数问题。说白了,同样的安全强度,ECDSA 的密钥只有 RSA 的十分之一。
为什么能这么短?用一张表对比一下:
| 安全强度(位) | RSA 密钥长度 | ECDSA 曲线 |
|---|---|---|
| 80 | 1024 | secp160 |
| 128 | 3072 | secp256 |
| 256 | 15360 | secp521 |
你想想看,RSA 3072 位签名有 384 字节,而 ECDSA 用 P-256 曲线签名才 64 字节。这在带宽受限的场景下优势非常明显。
但 ECDSA 有个坑:随机数必须足够随机。如果随机数重复,私钥就会被直接暴露。我记得有次审计发现某设备用了弱随机数生成器,连续两次签名用了相同的 k 值……那真是灾难。
经验之谈
如果 HSM 支持硬件随机数发生器(TRNG),一定要配置成强制使用。别依赖操作系统自带的随机数。
Ed25519:后起之秀,快且安全
Ed25519 是 Edwards 曲线的一种实现,属于 EdDSA 签名方案。它有几个让我特别喜欢的地方:
- 固定时间执行:没有分支依赖密钥,防止计时攻击
- 确定性签名:不需要额外随机数,签名哈希包含密钥哈希
- 超高性能:比 ECDSA 快 2-3 倍
- 签名长度:固定 64 字节(和 P-256 一样)
说白了,Ed25519 把 ECDSA 的那些坑都填平了。我最近做的一个金融级签名服务,从头到尾只用了 Ed25519。为什么呢?
第一,不需要担心随机数质量。第二,验签性能好,客户端多也不怕。第三,实现简单,代码量不到 RSA 的五分之一。
性能对比(HSM 实测数据)
| 算法 | 签名/秒 | 验签/秒 | 签名大小 |
|---|---|---|---|
| RSA-2048 | ~500 | ~8000 | 256 字节 |
| ECDSA P-256 | ~2000 | ~2500 | 64 字节 |
| Ed25519 | ~5000 | ~7000 | 64 字节 |
三种算法,怎么选?
我个人的决策套路是这样的:
- 兼容性优先:那就 RSA 2048 位。浏览器、老设备、PKI 协议都支持。
- 性能优先:选 Ed25519。尤其在高并发签名场景下,优势明显。
- 标准合规:很多政务、金融要求使用国密 SM2,但本质上也是 ECDSA 变种。
注意
不要自己实现签名算法,永远使用 HSM 内部的原生计算。我曾经见过有人把私钥导出到应用层做签名,结果内存被 dump 导致泄露。