4、非对称加密基础:RSA算法原理、ECC算法原理、密钥对生成与管理、加密与签名区别

各位同学,欢迎来到固件签名链的第一块基石——非对称加密。说实话,我在做固件安全之前,总觉得加密算法是数学家的玩具。直到有一次,我在一个IoT设备上发现私钥被硬编码在Flash里,整个签名链形同虚设……嗯,从那以后,我深刻理解了:不懂算法原理,你就没法真正保护你的签名链。

这一章,我们不搞复杂的数学推导,而是从工程角度,把RSA、ECC、密钥管理、签名与加密的区别讲透。你想想看,固件签名链的核心就是“用私钥签名,用公钥验签”,如果连这些基础都搞混,后面的完整性验证就是空中楼阁。

4.1 RSA算法原理:大数分解的硬骨头

RSA,说白了就是“大数分解很难”这个数学事实。我刚开始接触时也觉得玄乎,其实核心就三步:选两个大素数、算乘积、找一对互逆的指数。

RSA核心流程(简化版):

  1. 选素数:随机选两个大素数 p 和 q(比如各1024位)
  2. 算模数:n = p × q,n 就是公钥和私钥都依赖的模数
  3. 算欧拉函数:φ(n) = (p-1)(q-1)
  4. 选公钥指数:选 e(常用65537),要求 1 < e < φ(n) 且 gcd(e, φ(n)) = 1
  5. 算私钥指数:d ≡ e⁻¹ mod φ(n),即 e×d ≡ 1 mod φ(n)

加密时:c = me mod n(m是明文,c是密文)
解密时:m = cd mod n

我在项目中遇到过一个问题:有人为了性能,把 p 和 q 选得太接近,结果被费马分解法轻松攻破。所以记住,p 和 q 的位数要差不多,但数值差距要大,这是工程上的铁律。

避坑指南:我曾经见过一个固件,RSA密钥对生成时用了弱随机数生成器,导致多个设备的 p 值相同。攻击者只要拿到两个公钥 n₁ 和 n₂,计算 gcd(n₁, n₂) 就能分解出共享的素数——整个签名链直接报废。所以,随机数质量是RSA的生命线。

4.2 ECC算法原理:椭圆曲线上的离散对数

ECC(椭圆曲线密码学)是RSA的“年轻对手”。它用更短的密钥达到同等安全强度。为什么?因为椭圆曲线上的离散对数问题比大数分解更难啃。

ECC的核心是一个椭圆曲线方程:y² = x³ + ax + b(外加一个无穷远点)。在这个曲线上,我们可以定义“点加法”:P + Q = R。然后通过重复加法实现“标量乘法”:kP = P + P + ... + P(k次)。

私钥就是一个随机大整数 k,公钥就是 kP(P是曲线上的基点)。给你公钥 kP 和基点 P,让你求 k——这就是椭圆曲线离散对数问题,目前没有多项式时间解法。

对比项 RSA(2048位) ECC(256位)
安全强度 112位对称等价 128位对称等价
密钥长度 2048位 256位
签名速度 较慢 较快
验签速度 较快 较慢
典型曲线 — secp256r1, Curve25519

我个人习惯在资源受限的嵌入式设备上用ECC,因为256位的密钥比2048位的RSA密钥小得多,存储和传输都省空间。但要注意,ECC的验签比RSA慢,如果你的设备需要频繁验签(比如OTA升级时),得权衡一下。

经验之谈:在固件签名场景中,签名是一次性的(发布时签一次),验签是多次的(每个设备每次升级都要验)。所以如果验签性能是瓶颈,RSA反而有优势。我做过一个项目,用ECC验签导致启动时间多了2秒,后来切回RSA才达标。

4.3 密钥对生成与管理:从随机数到安全存储

密钥对生成,听起来简单,但坑特别多。我见过太多“生成即泄露”的案例了。

生成步骤:

  1. 熵源采集:从硬件随机数生成器(TRNG)或操作系统熵池获取足够熵
  2. 素数生成(RSA)或标量生成(ECC):用Miller-Rabin等算法验证素数性
  3. 密钥结构化:组装成标准格式(如PEM、DER、PKCS#8)
  4. 安全存储:私钥必须加密存储,公钥可以公开但需要完整性保护

密钥管理黄金法则:

  • 私钥永远不离开安全硬件(HSM、TEE、SE)
  • 公钥必须通过带外安全渠道分发(比如工厂预置、证书链)
  • 定期轮换密钥,旧密钥要安全销毁
  • 备份密钥时,用门限方案(Shamir秘密共享)拆分

我曾经在一个客户现场,发现他们把固件签名私钥放在一个共享文件夹里,权限是777。我问他们为什么,回答是“方便CI/CD流水线调用”。嗯,从那以后,我坚持所有签名操作必须在离线HSM上完成,流水线只能调用签名API,永远不能接触私钥原文。

4.4 加密与签名区别:两个完全不同的世界

这是初学者最容易混淆的地方。我面试时经常问:“RSA加密和RSA签名有什么区别?”一半人答不上来。

核心区别一句话:加密是为了保密,签名是为了认证。

维度 加密 签名
目的 防止第三方读取 证明发送者身份和内容完整性
使用密钥 公钥加密,私钥解密 私钥签名,公钥验签
输出 密文(与原文等长或略长) 签名值(固定长度)
可逆性 可解密还原原文 不可还原原文(只验证)
典型场景 传输密钥、加密固件包 固件签名、代码签名

在固件签名链中,我们只用签名,不用加密。为什么?因为固件本身通常是公开的(或者用对称加密保护),我们真正需要的是“这个固件是谁签的”和“固件有没有被篡改”。签名正好提供这两个保证。

常见误区:有人用RSA加密代替签名,把公钥加密后的密文当签名用。这是错的!加密不提供防抵赖性,而且如果公钥公开,任何人都能解密。签名用的是私钥,只有私钥持有者才能生成有效签名,这才是固件信任链的根基。

4.5 知识体系总览

下面这张图,把本章的核心逻辑串起来了。你可以把它当作一个思维导图,每次做固件签名时,对照着检查一遍。

非对称加密与固件签名知识体系 非对称加密与固件签名知识体系 非对称加密 RSA算法 大数分解难题 p, q, n, e, d 五元组 密钥长度:2048/4096位 ECC算法 椭圆曲线离散对数 私钥k,公钥kP 密钥长度:256位 密钥对管理 生成 → 存储 → 分发 → 轮换 HSM/TEE/SE 安全存储 加密 vs 签名 加密:公钥加密,私钥解密 签名:私钥签名,公钥验签 固件签名链只用签名,不用加密

这张图里,RSA和ECC是两种实现非对称加密的具体算法,密钥管理是它们的“生存环境”,而加密与签名的区别决定了我们在固件场景中怎么用它们。四者缺一不可。

我的建议:刚开始学的时候,先别纠结数学细节。你只需要记住:RSA靠大数分解,ECC靠椭圆曲线离散对数;签名用私钥,验签用公钥;密钥必须安全存储。把这些工程直觉建立起来,后面学签名链就顺了。