3、非对称加密算法详解:RSA算法原理、ECC椭圆曲线算法、密钥长度与安全强度

聊到固件签名验签,绕不开的核心就是非对称加密。说白了,它就像一把特制的锁——你用公钥锁上,只有私钥能打开;或者反过来,私钥签名,公钥验证。这种机制让固件发布者能证明“这东西是我发的,没人动过”。

这一章,我带你拆解两个最主流的算法:RSA 和 ECC。嗯,它们背后的数学其实不复杂,但坑不少。我踩过几次,今天一并说清楚。

3.1 RSA 算法:大数分解的硬骨头

RSA 是 1977 年诞生的老将,到今天依然是应用最广的非对称算法。它的安全性建立在“大整数分解”的数学难题上——两个大质数乘起来容易,但把乘积拆回质数,难如登天。

3.1.1 密钥生成流程

我个人习惯把 RSA 密钥生成拆成五步,这样好记:

  1. 选两个大质数:p 和 q,长度要接近,且不能太接近(否则容易被猜)。
  2. 计算 n:n = p × q。n 就是公钥和私钥都用到的大数。
  3. 计算欧拉函数 φ(n):φ(n) = (p-1) × (q-1)。
  4. 选公钥指数 e:通常取 65537(0x10001),它是个质数,且计算效率高。
  5. 计算私钥 d:d 是 e 关于 φ(n) 的模逆元,满足 e × d ≡ 1 (mod φ(n))。

关键点:私钥 d 一旦泄露,整个体系就完了。我在项目中见过有人把私钥硬编码在固件里,结果被反编译直接提取——那场面,惨不忍睹。

3.1.2 签名与验签过程

RSA 签名验签的逻辑其实很直观:

  • 签名:用私钥 d 对消息的哈希值做模幂运算,得到签名值 s = hash(m)^d mod n。
  • 验签:用公钥 (n, e) 对签名值做模幂运算,得到 hash' = s^e mod n,然后对比 hash' 是否等于原始消息的哈希值。

你想想看,这里有个细节:签名用的是私钥,验签用的是公钥。这和加密正好反过来。我刚开始做固件安全时,总把这两个搞混,后来在调试一个 OTA 升级模块时,因为签名验签方向搞反,折腾了两天才发现——嗯,从那以后我再也没犯过。

3.1.3 密钥长度与安全强度

RSA 的密钥长度直接决定安全等级。下面这张表是我常用的参考:

RSA 密钥长度(位) 安全等级(对称加密等价) 推荐用途
1024 80 位 已不推荐,可被国家力量破解
2048 112 位 当前最低标准,适合大多数固件
3072 128 位 推荐用于高安全场景
4096 192 位 军工级,但计算开销大

避坑指南:我曾经接手过一个遗留项目,用的 RSA-1024。当时 NIST 已经明确要求 2048 位以上,但客户觉得“够用就行”。结果半年后,有安全团队用经典数域筛法(NFS)在云上花了两周就分解了那个 1024 位的 n。从那以后,我坚持所有新项目至少 2048 位起步。

3.2 ECC 椭圆曲线算法:短密钥,高强度

ECC 是 1985 年提出的后起之秀。它的安全性建立在“椭圆曲线离散对数问题”上——给定基点 G 和公钥 Q = kG,求私钥 k 几乎不可能。ECC 最大的优势是:同样安全强度下,密钥长度比 RSA 短得多。

3.2.1 椭圆曲线数学基础

别被“椭圆曲线”这个名字吓到。它其实就是满足方程 y² = x³ + ax + b 的点集,再加上一个无穷远点。在有限域上,这些点构成一个循环群。

ECC 的核心操作是标量乘法:k × G,其中 k 是私钥(一个大整数),G 是基点。这个操作可以分解为点加和倍点运算。举个例子:

// 伪代码:计算 11 * G
// 11 的二进制是 1011
result = 0
for bit in bits_of_11:
    result = double(result)   // 倍点
    if bit == 1:
        result = add(result, G)  // 点加
return result

你想想看,这个算法和 RSA 的模幂运算很像,但 ECC 的密钥长度只有 RSA 的 1/10 左右,就能达到相同安全等级。这在资源受限的嵌入式设备上,简直是福音。

3.2.2 常用曲线与参数

ECC 的安全性高度依赖曲线参数的选择。我建议你直接用标准曲线,别自己造。以下是几个主流曲线:

曲线名称 密钥长度(位) 安全等级 适用场景
secp256r1 (P-256) 256 128 位 通用固件签名,NIST 推荐
secp384r1 (P-384) 384 192 位 高安全场景,如金融设备
Curve25519 (X25519) 256 128 位 高性能嵌入式,无专利限制
secp521r1 (P-521) 521 256 位 军工级,但计算开销大

个人建议:对于大多数嵌入式固件签名场景,secp256r1 或 Curve25519 就足够了。Curve25519 的设计更抗侧信道攻击,我最近几个项目都在用这个。

3.2.3 ECDSA 签名验签流程

ECDSA(椭圆曲线数字签名算法)是 ECC 在签名场景的标准实现。流程如下:

  • 签名:
    1. 生成随机数 k,计算点 R = k × G,取 R 的 x 坐标 r。
    2. 计算 s = k⁻¹ × (hash(m) + r × d) mod n,其中 d 是私钥。
    3. 签名值为 (r, s)。
  • 验签:
    1. 检查 r 和 s 是否在有效范围内。
    2. 计算 u1 = hash(m) × s⁻¹ mod n,u2 = r × s⁻¹ mod n。
    3. 计算点 P = u1 × G + u2 × Q,其中 Q 是公钥。
    4. 验证 P 的 x 坐标是否等于 r。

致命陷阱:ECDSA 的随机数 k 必须每次不同且真正随机。我曾经见过一个项目,因为随机数生成器坏了,每次签名都用同一个 k,结果攻击者通过两个签名直接算出了私钥。嗯,这就是著名的“随机数重用攻击”。所以,一定要用硬件真随机数发生器(TRNG),别偷懒用伪随机。

3.3 RSA vs ECC:如何选择?

这两个算法各有千秋。下面这张对比表,是我在实际选型时用的:

对比维度 RSA ECC
密钥长度(128 位安全等级) 3072 位 256 位
签名速度 慢(私钥操作) 快(私钥操作)
验签速度 快(公钥操作) 慢(公钥操作)
签名大小 与密钥长度相同(如 256 字节) 固定(如 64 字节)
抗量子计算 弱(Shor 算法可破解) 弱(Shor 算法可破解)
嵌入式资源占用 高(大数运算) 低(适合 MCU)

我个人习惯这样选:如果设备是 Cortex-M4 以上的 MCU,且对验签速度要求高(比如每秒验签上千次),我会选 RSA-2048。如果设备是 Cortex-M0 这种资源受限的,或者固件包大小敏感,我会选 ECC-256。你想想看,ECC 的签名只有 64 字节,而 RSA-2048 的签名是 256 字节——在 OTA 升级时,这个差距很明显。

3.4 密钥长度与安全强度的深层理解

很多人以为“密钥越长越安全”,其实不完全对。安全强度不是线性增长的。RSA-2048 的安全强度是 112 位,而 RSA-4096 是 192 位——密钥长度翻倍,安全强度只增加了 80 位。而且,密钥越长,计算开销越大,在嵌入式设备上可能慢到不可接受。

我建议你参考 NIST SP 800-57 的标准:

  • 2023-2030 年:至少 112 位安全强度(RSA-2048 / ECC-224)。
  • 2030 年以后:至少 128 位安全强度(RSA-3072 / ECC-256)。
  • 长期(2050+):考虑抗量子算法(如 CRYSTALS-Dilithium)。

核心原则:不要追求“最大密钥”,而是追求“够用且高效”。对于固件签名,RSA-2048 或 ECC-256 是目前最平衡的选择。我见过有人用 RSA-8192,结果每次签名要等 3 秒,用户直接投诉——这就是过度设计。

3.5 本章知识体系图

下面这张图,帮你把 RSA 和 ECC 的核心脉络理清楚:

非对称加密算法知识体系 非对称加密算法知识体系 非对称加密 RSA 算法 数学基础:大整数分解 密钥生成:p, q, n, e, d 签名:s = hash(m)^d mod n 验签:hash' = s^e mod n 推荐:RSA-2048 / RSA-3072 ECC 算法 数学基础:椭圆曲线离散对数 密钥生成:私钥 k,公钥 Q = kG 签名:(r, s) 基于随机数 k 验签:P = u1G + u2Q 推荐:secp256r1 / Curve25519 核心原则:够用且高效,不盲目追求大密钥

这张图把 RSA 和 ECC 的数学基础、密钥生成、签名验签流程以及推荐配置都串起来了。你可以把它当作选型时的快速参考。

3.6 小结与避坑清单

这一章的内容不少,我帮你总结几个关键点:

  • RSA 适合验签频繁的场景:公钥操作快,但私钥操作慢,密钥体积大。
  • ECC 适合资源受限的设备:密钥短,签名小,但验签计算量稍大。
  • 密钥长度不是越长越好:RSA-2048 和 ECC-256 是当前最平衡的选择。
  • 随机数质量是 ECDSA 的生命线:一定要用硬件 TRNG,别用伪随机。
  • 标准曲线优先:别自己造曲线,用 secp256r1 或 Curve25519 就对了。

最后一句:我在实际项目中,80% 的固件签名场景用的是 ECC-256(secp256r1),剩下 20% 是 RSA-2048。选哪个,取决于你的硬件能力和性能要求。嗯,记住一点:安全是设计出来的,不是堆出来的。