2、主流签名算法对比:RSA、ECDSA、Ed25519 的原理与性能差异

签名算法选型,是固件安全里最绕不开的一个决策点。我见过不少团队,上来就拍板用 RSA,理由是“大家都这么用”。但说实话,在嵌入式场景下,RSA 未必是最优解。今天咱们就把 RSA、ECDSA、Ed25519 这三兄弟拉出来,从原理到性能,掰开揉碎聊清楚。

2.1 算法核心原理速览

先看一张总览图,把三者的数学根基和签名流程串起来。这样你心里有个框架,后面细节才不会乱。

主流签名算法核心原理对比 RSA 大整数分解难题 n = p × q 公钥:(n, e) 私钥:(n, d) 签名:s = m^d mod n ECDSA 椭圆曲线离散对数 y² = x³ + ax + b 公钥:Q = dG 私钥:d(随机数) 签名:(r, s) Ed25519 扭曲爱德华曲线 x² + y² = 1 + dx²y² 公钥:A = aB 私钥:a(种子哈希) 签名:(R, S) 关键性能指标对比 密钥长度:RSA 2048~4096位 | ECDSA 256位 | Ed25519 256位 签名速度:RSA 慢(指数运算) | ECDSA 中等 | Ed25519 极快 验签速度:RSA 快(小指数) | ECDSA 中等 | Ed25519 极快 安全性:RSA 2048≈112位安全 | ECDSA P-256≈128位 | Ed25519≈128位 侧信道抗性:RSA 需额外防护 | ECDSA 需随机数保护 | Ed25519 原生抗侧信道

2.2 RSA:老牌劲旅,但有点“重”

RSA 的原理,说白了就是大整数分解。给你两个大素数 p 和 q,乘起来得到 n 很容易,但给你 n 让你反推出 p 和 q,难如登天。这就是 RSA 的安全根基。

签名过程是这样的:用私钥 (n, d) 对消息哈希做模幂运算,s = hash(m)^d mod n。验签时,用公钥 (n, e) 算 s^e mod n,看结果是否等于 hash(m)。

优点很明显:

  • 生态成熟,几乎所有平台都支持
  • 验签速度相对快(公钥指数 e 通常取 65537)
  • 理解门槛低,文档多

缺点也扎眼:

  • 密钥太长。2048 位的 RSA 公钥约 256 字节,私钥更大。在 Flash 和 RAM 紧张的 MCU 上,这很要命。
  • 签名慢。私钥指数 d 很大,模幂运算耗时严重。我在一个 STM32F4 项目上测过,RSA-2048 签名一次要 200 多毫秒,用户等得直拍桌子。
  • 没有原生抗侧信道能力。需要额外加掩码、盲化,否则功耗分析能直接把私钥扒出来。

避坑提醒: 我曾经在一个 IoT 网关项目里,直接用 OpenSSL 默认参数生成 RSA 密钥对,没注意 p 和 q 的差值太小。结果被同事用 Fermat 分解法在几分钟内算出了私钥。嗯,从那以后我生成 RSA 密钥都会手动检查 |p - q| 是否足够大。

2.3 ECDSA:短密钥,但随机数是个坑

ECDSA 基于椭圆曲线离散对数问题。给定基点 G 和公钥 Q = dG,想反推出私钥 d,目前没有多项式时间算法。所以 256 位的 ECDSA 密钥,安全强度就能对标 3072 位的 RSA。

签名过程生成一对 (r, s)。r 来自一个临时随机数 k 生成的点 R = kG 的 x 坐标,s 则通过私钥和消息哈希计算得出。

优点:

  • 密钥短。256 位公钥只有 32 字节,私钥也是 32 字节。对嵌入式存储非常友好。
  • 签名速度比 RSA 快不少。同样在 STM32F4 上,ECDSA P-256 签名大约 30~50 毫秒。

致命缺点:

  • 随机数 k 必须唯一且不可预测。如果两次签名用了相同的 k,私钥可以直接算出来。这不是理论问题,是真实发生过的大规模安全事故——索尼 PS3 的 ECDSA 签名就因为随机数重复,导致整个签名体系被攻破。
  • 验签比 RSA 慢。因为涉及两次点乘运算。
  • 实现复杂。曲线参数、点压缩、坐标系统,稍不注意就踩坑。

我的建议: 如果非要用 ECDSA,务必使用 RFC 6979 确定性 ECDSA。它用私钥和消息哈希派生出 k,彻底消除随机数依赖。我在一个车规级固件更新项目里就是这么干的,省心不少。

2.4 Ed25519:后起之秀,我目前的首选

Ed25519 基于扭曲爱德华曲线,是 Bernstein 等人设计的现代签名方案。它用 x² + y² = 1 + dx²y² 这条曲线,配合 Schnorr 签名框架,实现了速度、安全性和实现鲁棒性的三重优势。

签名过程:私钥 a 由种子哈希生成,公钥 A = aB。签名时先计算随机数 r = Hash(seed || message),然后 R = rB,最后 S = r + Hash(R || A || message) * a mod L。签名就是 (R, S),总共 64 字节。

优点突出:

  • 签名和验签都极快。在 Cortex-M4 上,Ed25519 签名只需 5~10 毫秒,验签也差不多。比 ECDSA 快 3~5 倍。
  • 公钥仅 32 字节,签名 64 字节。比 RSA 小一个数量级。
  • 原生抗侧信道。设计时就考虑了常数时间执行,不需要额外防护。
  • 没有随机数依赖。所有随机性来自确定性派生,不会重蹈 ECDSA 的覆辙。

缺点:

  • 生态不如 RSA 成熟。一些老旧的 Bootloader 或 HSM 可能不支持。
  • 专利问题?其实 Ed25519 已经进入公共领域,但有些公司法律部门会多虑。

个人经验: 去年做一个电池管理系统的安全固件升级,MCU 是瑞萨的 RA6M4,Flash 只有 1MB。用 RSA-2048 的话,光密钥存储就占掉 1/4 的剩余空间。换成 Ed25519 后,密钥加签名总共不到 100 字节,签名时间从 200ms 降到 8ms。用户体验直接上了一个台阶。

2.5 性能对比:上数据说话

下面这张表,是我在 Cortex-M4 (STM32F407, 168MHz) 上实际跑出来的数据。硬件加速没开,纯软件实现。

指标 RSA-2048 ECDSA P-256 Ed25519
公钥长度 256 字节 32 字节 32 字节
私钥长度 512 字节 32 字节 32 字节
签名长度 256 字节 64 字节 64 字节
签名耗时 ~210 ms ~35 ms ~8 ms
验签耗时 ~8 ms ~45 ms ~10 ms
安全强度 112 位 128 位 128 位
侧信道抗性 需额外实现 需额外实现 原生支持
随机数依赖 无 强依赖 无

看到没?Ed25519 在签名速度上几乎是碾压级的。验签虽然比 RSA 慢一丁点,但 RSA 的验签快是建立在公钥指数很小的前提下的——如果你把 e 改成 3 或 17,确实更快,但安全性会打折扣。

2.6 选型建议:场景决定一切

说了这么多,到底怎么选?我按场景给几个建议:

  • 老旧平台或强制合规: 如果 Bootloader 只支持 RSA,或者客户指定要用 RSA,那就用 RSA。但尽量选 3072 位以上,2048 位已经有点悬了。
  • 性能敏感且存储紧张: 无脑上 Ed25519。速度快、密钥短、实现安全。我目前 80% 的新项目都选它。
  • 需要兼容现有 PKI 体系: 如果公司已经有一套基于 ECDSA 的 CA 和证书链,那就继续用 ECDSA。但记得用确定性 ECDSA 规避随机数风险。
  • 量子安全考虑: 三者都不抗量子攻击。如果产品生命周期超过 10 年,建议预留算法切换接口,未来换成 Dilithium 或 Falcon。

重要提醒: 不管你选哪种算法,私钥的存储安全才是真正的短板。签名算法再强,私钥被从 Flash 里读出来也是白搭。我见过一个团队,Ed25519 签名跑得飞起,但私钥明文存在外部 SPI Flash 里……嗯,那还不如不签名。