常见签名算法:RSA、DSA、ECDSA、Ed25519 对比与选择
做签名验证,绕不开算法选型。说实话,这步选错了,后面全白搭。
我见过不少项目,上来就拍脑袋用 RSA 2048,理由是“大家都用这个”。结果到了 IoT 设备里,芯片算力跟不上,签名搞了 200 毫秒——连握手都超时了。反过来,也有客户非要用 Ed25519,但 HSM 不支持,最后只能用软件实现,密钥裸奔在内存里。
所以这节课,我带你把这四种算法掰开揉碎看一遍。不搞数学推导,就讲实际工程怎么选。
RSA —— 老大哥,但真不慢
RSA 是最常见的签名算法,国内政企项目几乎标配。它的强项是验证快,签名慢。验证快到什么程度?用公钥指数 65537,验证一次比签名快上百倍。你想想看,服务端每天要校验上亿次签名,这优势就出来了。
但 RSA 有个硬伤:密钥太长。2048 位 RSA 密钥都快 512 字节了,4096 位更别提。有些 HSM 内部生成 4096 位的密钥对,要等 5〜10 秒。我去年帮一个金融机构做审计,发现他们还在用 1024 位 RSA,吓得我赶紧建议迁移——1024 位早在 2015 年就被 NIST 禁了。
DSA —— 能不用就别用了
DSA 是标准里早年的选择,但说实话,现在有点尴尬。
它的签名比 RSA 快,验证却慢。而且密钥生成需要找一个安全的素数 p 和 q,这个过程极其耗时。更讨厌的是,DSA 必须在每次签名时生成一个随机数 k,一旦 k 泄露或复用,私钥就暴露了。我记得 2010 年索尼 PS3 的签名密钥泄露,就是因为 k 重复使用——一个游戏主机帝国就这么被破了。
现在 FIPS 虽然还支持 DSA,但主流 HSM 厂商都在淡化它。我自己的项目里,唯一用到 DSA 的场景是跟遗留系统对接——说白了就是擦屁股。
ECDSA —— 短密钥,高性能,但坑也多
ECDSA 是目前的主流。256 位椭圆曲线就能提供跟 RSA 3072 同等级的安全强度。密钥短、签名短、计算快,特别适合移动端和 IoT。
但 ECDSA 有个让我印象深刻的问题:曲线选择。市面上有 NIST P-256、secp256k1(比特币用的)、SM2(国密)。不同 HSM 支持的曲线不一样,选不对就跑不起来。我曾经有个项目,HSM 是恩智浦的 EdgeLock,只支持 P-256 和 Brainpool,结果业务方要求用 secp256r1——查了半天才确认两者等价,但文档里叫法不同,差点翻车。
此外,ECDSA 的签名值编码方式也有坑:DER 编码还是原始 R||S?很多服务端库只认 DER,你如果发了原始 R||S 过去,验签就失败。一开始没注意,排查了两天。
Ed25519 —— 新生代,几乎无坑
Ed25519 我用下来感觉最省心。它是 Edwards 曲线上的数字签名算法,属于 EdDSA 系列。设计上考虑了防侧信道、防定时攻击,而且签名时不需要随机数——基于确定性签名,你不可能复用 k。
它的签名速度快到离谱。在 ARM Cortex-M4 上,一个 Ed25519 签名只需要 2 毫秒出头,验签也差不多。RSA 2048 在那个平台上至少 50 毫秒。差距不是一个量级。
不过,Ed25519 有个小麻烦:HSM 支持率不高。像 Thales Luna、Utimaco 这些高端 HSM 近年才陆续支持,而一些低成本的 TPM 芯片至今不支持。另外,Ed25519 的签名值固定 64 字节,有些标准协议(比如 CMS/PKCS#7)对它适配得不完全,需要额外包装。
核心对比:一张表看明白
下面这个表是我自己整理的项目选型参考,建议你直接收藏。
| 特性 | RSA 2048 | DSA 2048 | ECDSA P-256 | Ed25519 |
|---|---|---|---|---|
| 安全强度 | 112 位 | 112 位 | 128 位 | 128 位 |
| 公钥长度 | 256 字节 | 256 字节 | 32 字节 | 32 字节 |
| 签名长度 | 256 字节 | ~64 字节 | ~70 字节(DER) | 64 字节 |
| 签名速度(相对) | 慢 | 中等 | 快 | 极快 |
| 验证速度(相对) | 极快 | 慢 | 快 | 极快 |
| 随机数需求 | 无(签名不需) | 有(致命) | 有 | 无(确定性) |
| HSM 支持度 | 绝大部分 | 大部分 | 绝大部分 | 新兴,增长中 |
| 合规认可度 | 最高 | 低(正在淘汰) | 高 | 中等(FIPS 未全认证) |
选择决策流程
我画了一张图,帮你快速做决策。记住:先看 HSM 支持哪些算法,再看业务需求。
实战避坑清单
- 密钥存储:不要把私钥放在代码里或明文文件。用 HSM 或安全元件,实在不行用加密的 PKCS#8 文件。
- 签名格式:ECDSA 的 DER 编码和原始 R||S 容易搞混。测试环境先对齐。
- 哈希算法:签名之前一定要用强哈希。RSA 用 SHA-256,ECDSA/Ed25519 用 SHA-512 或内置的 SHA-512。不要用 MD5 或 SHA-1,那是炸弹。
- HSM 升级:更换 HSM 时,要保证新硬件支持你选的算法。我曾经从不支持 Ed25519 的 HSM 迁移到支持版本,硬改了整个签名链——教训深刻。
好了,四种算法讲完了。记住一点:选型没有银弹。根据 HSM 能力、业务场景、性能要求、合规需求来定。下节课我们讲具体怎么用 HSMs 接口封装签名操作——到时候就能用上今天选好的算法了。