3、经典签名算法详解:RSA-PSS、ECDSA、EdDSA的原理、参数选择与安全强度

聊到经典签名算法,我得先坦白一件事。我入行那会儿,RSA 就是签名的代名词。后来 ECDSA 火了,再后来 EdDSA 开始被大家重视。现在要迁移到 PQC,你反而得把这些老家伙彻底搞明白——因为迁移的本质,就是拿新算法去替换它们。你不了解要替换的对象,迁移方案就是空中楼阁。

这一章,我把三个最主流的经典签名算法掰开揉碎了讲。原理、参数、安全强度,一个都不放过。

3.1 RSA-PSS:老将的自我修养

RSA-PSS,全称 RSA Probabilistic Signature Scheme。说白了,它就是 RSA 签名的一个安全补丁版本。

早期的 RSA 签名用的是 PKCS#1 v1.5 填充。那个方案有个毛病——签名是确定性的。同样的消息,每次签名结果一模一样。这给了攻击者可乘之机,比如 Bleichenbacher 攻击就是利用这个特性搞事情。

PSS 的改进思路很直接:引入随机数。每次签名前,往消息里混入一个随机盐值(salt)。这样一来,同样的消息每次签名结果都不同。攻击者想搞选择明文攻击?难度直接翻倍。

原理简述

RSA-PSS 的签名流程大致分三步:

  1. 消息编码:把原始消息通过哈希函数处理,再跟随机盐值、填充字节拼在一起,形成一个固定长度的编码结果。
  2. 签名生成:用私钥对编码结果做 RSA 模幂运算,得到签名值。
  3. 签名验证:用公钥做模幂运算,恢复出编码结果,然后反向解码,比对哈希值是否一致。

嗯,这里要注意:PSS 的编码过程比 v1.5 复杂得多。它用了掩码生成函数(MGF1)来扩散随机性。我当年第一次实现 PSS 时,被 MGF1 的嵌套循环搞得头晕。后来发现,其实只要按标准一步步来,没那么玄乎。

参数选择

RSA-PSS 的参数选择,核心就两个:模数长度和盐值长度。

参数 推荐值 说明
模数长度 2048 / 3072 / 4096 位 2048 位目前安全,但建议新系统直接上 3072 位
盐值长度 等于哈希输出长度 比如 SHA-256 就用 32 字节,别偷懒
哈希函数 SHA-256 / SHA-384 别用 SHA-1,已经废了

我的经验:盐值长度别小于哈希输出长度。我在一个项目里见过有人把盐值设成 0——那跟 PKCS#1 v1.5 有什么区别?安全强度直接打回原形。

安全强度

RSA-PSS 的安全性依赖于大整数分解问题的困难性。目前 2048 位 RSA 大概提供 112 位安全强度,3072 位对应 128 位。但注意,这是经典计算下的评估。量子计算机来了,Shor 算法直接把它秒成渣——这也是我们为什么要迁移到 PQC。

3.2 ECDSA:椭圆曲线上的签名舞者

ECDSA,Elliptic Curve Digital Signature Algorithm。它跟 RSA 走的是完全不同的路子。RSA 靠大整数分解,ECDSA 靠椭圆曲线离散对数问题(ECDLP)。

我个人习惯把 ECDSA 比作「短签名」的代表。同样安全强度下,ECDSA 的签名长度和密钥长度都比 RSA 短得多。256 位 ECDSA 的安全强度约等于 3072 位 RSA。这在 IoT 设备上简直是天大的优势——你想想看,一个传感器芯片的存储空间就那么点,用 RSA 可能连密钥都塞不下。

原理简述

ECDSA 的签名过程涉及椭圆曲线上的点乘运算。大致流程:

  1. 生成一个随机数 k,计算 k * G(G 是基点),得到点 R。
  2. 用 R 的 x 坐标计算签名分量 r。
  3. 用私钥、消息哈希和 r 计算签名分量 s。
  4. 签名就是 (r, s) 对。

验证时,验证方用公钥、消息哈希和签名 (r, s) 恢复出点 R',然后比对 R' 的 x 坐标是否等于 r。

我曾经踩过的坑:随机数 k 绝对不能重复使用!如果两次签名用了同一个 k,攻击者可以直接算出私钥。2010 年索尼 PS3 的 ECDSA 签名被破解,就是因为 k 是固定的。嗯,这个教训是用真金白银换来的。

参数选择

ECDSA 的参数选择比 RSA 复杂,因为涉及曲线类型。主流选择:

曲线 密钥长度 安全强度 适用场景
P-256 (secp256r1) 256 位 128 位 通用,NIST 推荐
P-384 (secp384r1) 384 位 192 位 高安全场景
P-521 (secp521r1) 521 位 256 位 极高标准
secp256k1 256 位 128 位 区块链场景(比特币)

我建议 IoT 固件签名优先选 P-256。原因很简单:硬件加速支持最广泛。很多 MCU 芯片内置了 P-256 的硬件加速单元,签名验签速度能快一个数量级。

安全强度

ECDSA 的安全性基于 ECDLP。经典计算下,256 位曲线提供 128 位安全强度。但量子计算来了,情况跟 RSA 一样惨——Shor 算法同样能破解 ECDLP。所以 ECDSA 也在被替换之列。

3.3 EdDSA:后起之秀的优雅设计

EdDSA,Edwards-curve Digital Signature Algorithm。它是 Daniel J. Bernstein 等人设计的,基于扭曲爱德华曲线(Edwards curve)。

说实话,我第一次接触 EdDSA 时,觉得它比 ECDSA 优雅太多了。为什么?因为它解决了 ECDSA 的几个老大难问题:

  • 确定性签名:EdDSA 不需要随机数生成器。签名结果是确定性的,但通过哈希私钥和消息来模拟随机性,既安全又省心。
  • 侧信道攻击防护:EdDSA 的运算不依赖秘密数据的分支和查表,天然抗时序攻击。
  • 批量验证:EdDSA 支持高效的批量签名验证,这在固件更新场景下特别有用。

原理简述

EdDSA 的核心是 Ed25519(基于 Curve25519)。签名过程:

  1. 用哈希函数处理私钥,得到两个部分:一个用于生成随机数 r,一个用于生成公钥。
  2. 计算 r * G 得到点 R。
  3. 用消息哈希、R 和公钥计算挑战值 h。
  4. 计算签名分量 s = r + h * 私钥。
  5. 签名就是 (R, s) 对。

验证时,验证方计算 h,然后检查 s * G 是否等于 R + h * 公钥。整个过程干净利落。

关键区别:EdDSA 的签名是 (R, s),而 ECDSA 是 (r, s)。EdDSA 直接传递点 R,省去了从 x 坐标恢复点的步骤。这看起来是小改动,但实际实现时少了很多边界情况处理。

参数选择

EdDSA 的参数选择比 ECDSA 简单得多。主流就两个变种:

变种 曲线 密钥长度 安全强度 特点
Ed25519 Curve25519 256 位 128 位 速度极快,签名仅 64 字节
Ed448 Goldilocks 448 位 224 位 更高安全,签名 114 字节

我建议 IoT 场景无脑选 Ed25519。签名短、速度快、实现简单。我在一个资源受限的 MCU 上移植过 Ed25519,整个签名库才几 KB,跑起来比 ECDSA P-256 还快 30%。

安全强度

Ed25519 提供 128 位安全强度,Ed448 提供 224 位。同样,量子计算下它们都不安全。但 EdDSA 的设计理念——确定性、抗侧信道、简单实现——对 PQC 签名算法的设计有深远影响。你去看 Dilithium 和 Falcon 的设计,多少都借鉴了 EdDSA 的思路。

3.4 三剑客对比

我把三个算法放在一起对比,方便你选型时参考:

特性 RSA-PSS ECDSA EdDSA
数学基础 大整数分解 椭圆曲线离散对数 爱德华曲线离散对数
签名长度 256 字节 (2048位) 64 字节 (P-256) 64 字节 (Ed25519)
公钥长度 256 字节 32 字节 32 字节
签名速度 慢 中等 快
验证速度 快 中等 快
随机数需求 需要(盐值) 需要(k 值) 不需要(确定性)
抗侧信道 中等 弱(需额外防护) 强(设计内置)
硬件加速支持 广泛 广泛(P-256) 逐渐普及
量子安全 否 否 否

你看这个表,EdDSA 在 IoT 场景下几乎全面占优。但现实是,很多现有系统用的是 RSA-PSS 或 ECDSA。迁移到 PQC 时,你得考虑兼容性——不能一刀切把老算法全砍了,得逐步过渡。

3.5 知识体系总览

下面这张图把三个算法的核心脉络串起来了。你可以把它当作本章的「导航地图」。

经典签名算法知识体系 RSA-PSS ECDSA EdDSA 大整数分解 椭圆曲线离散对数 爱德华曲线离散对数 签名 256B / 公钥 256B 签名 64B / 公钥 32B 签名 64B / 公钥 32B 112~256 位 (2048~4096) 128~256 位 (P-256~P-521) 128~224 位 (Ed25519~Ed448) ❌ 量子不安全 ❌ 量子不安全 ❌ 量子不安全 ⬇ 迁移方向:经典签名 → PQC 签名(Dilithium / Falcon / SPHINCS+)

这张图把三个算法的数学基础、核心特性、安全强度和量子安全状态串在了一起。你看最下面那行——不管你现在用哪个,最终都要往 PQC 迁移。区别只是迁移路径和节奏不同。

3.6 迁移视角的思考

讲完这三个算法,我想从迁移视角给你几个建议:

  • 别急着全换:如果你的系统还在用 RSA-PSS 2048 位,短期内不用慌。先做兼容性评估,再规划迁移路径。
  • 优先考虑 EdDSA:如果系统还没定型,或者正在做架构升级,我建议先切到 EdDSA。它跟 PQC 签名的设计理念更接近,迁移时改动更小。
  • 关注混合签名方案:过渡期可以用经典签名 + PQC 签名的组合。比如固件同时携带 RSA-PSS 和 Dilithium 签名,验证方根据能力选择验证。这样既保证向后兼容,又逐步引入量子安全。

我的经验:在 IoT 固件签名场景下,我建议先做「签名算法抽象层」。把签名验证接口封装成统一的 API,底层可以切换算法。这样迁移时只需要换底层实现,上层固件更新逻辑完全不用动。这个抽象层我做了三次迭代才稳定下来——第一次太厚,性能损失大;第二次太薄,灵活性不够。第三次才找到平衡点。