第四节:公钥密码学基础:RSA算法原理、ECC算法原理、哈希函数(SHA-256)的作用

好,我们进入第四讲。前面几节我们聊了安全启动的整体架构、信任根、以及密钥管理。这一节,我们来啃一块硬骨头——公钥密码学。

说实话,很多做MCU开发的兄弟一听到「公钥密码学」就头大。我当年也一样。但做安全启动,你绕不开它。为什么呢?因为签名验证的核心,就是公钥算法。你想想看,固件在工厂里用私钥签名,设备端用公钥验证——这背后全是数学。

别怕,我不跟你推公式。我会用工程师的视角,把RSA、ECC、SHA-256这三个东西讲明白。尤其是它们在实际MCU上怎么用、有什么坑。

4.1 哈希函数:SHA-256,安全启动的「指纹」

我们先讲哈希函数。为什么?因为RSA和ECC签名,本质上都是「对哈希值签名」。没有哈希,签名效率会低到没法用。

哈希函数,说白了就是一个「压缩器」。你给它任意长度的数据,它给你一个固定长度的摘要。SHA-256的输出是256位,也就是32字节。

它的核心特性有三个:

  • 单向性:从摘要反推原始数据,几乎不可能。我试过暴力破解,算到天荒地老。
  • 抗碰撞性:很难找到两个不同的输入,产生相同的输出。嗯,理论上存在,但实际你找不到。
  • 雪崩效应:输入改一个比特,输出完全变样。

在安全启动里,SHA-256的作用是什么?

  • 对固件镜像计算哈希值,然后对这个哈希值做签名。
  • 验证时,先重新计算固件哈希,再验证签名。
  • 这样,签名只需要处理32字节,而不是整个固件(可能几MB)。

重要:哈希函数不是加密。它不保护数据机密性,只保证完整性。你想想看,固件本身可能是明文的,但哈希值被篡改的话,签名验证就会失败。

我在项目中遇到过一个问题:某款MCU的硬件哈希加速器只支持SHA-1,不支持SHA-256。但安全启动规范要求SHA-256。怎么办?只能用软件实现。嗯,这里要注意,软件SHA-256在低端MCU上很慢,一个128KB的固件可能要算好几秒。所以选型时一定要确认硬件支持。

实战建议:如果MCU有硬件哈希加速器,优先用。没有的话,可以考虑用HMAC-SHA256的软件库,比如mbedTLS。但要注意RAM占用——它需要64字节的工作缓冲区。

4.2 RSA算法原理:大数分解的「盾牌」

RSA,1977年诞生,至今仍是工业界最广泛使用的公钥算法。它的安全性基于一个数学难题:大整数分解。

简单说:两个大素数p和q相乘得到n,很容易。但从n反推出p和q,非常难。RSA就是利用这个不对称性。

RSA的核心参数:

  • 公钥:(n, e),其中n是模数,e是公钥指数(常用65537)。
  • 私钥:(n, d),d是私钥指数。
  • 签名:对哈希值h,计算 s = h^d mod n。
  • 验证:计算 h' = s^e mod n,比较h'是否等于h。

在MCU上,RSA的典型密钥长度是2048位。为什么?1024位已经被认为不安全,4096位又太慢。2048位是平衡点。

我曾经在一个项目里,用了一颗主频48MHz的Cortex-M0芯片做RSA-2048签名验证。你猜多久?大约1.2秒。嗯,对于安全启动来说,这个时间可以接受。但如果你的产品需要频繁验证(比如OTA升级),那就得考虑硬件加速了。

避坑指南:我曾经遇到过一个问题——RSA签名验证通过了,但固件还是跑不起来。查了半天,发现是公钥在存储时被意外修改了一个字节。RSA验证对公钥的完整性极其敏感。所以,公钥一定要放在OTP(一次性可编程)区域,或者用硬件保护。

RSA的优缺点:

优点 缺点
算法成熟,硬件支持广泛 密钥长(2048位),占用存储空间大
签名验证速度尚可(有硬件加速时很快) 签名生成慢(私钥操作需要大数模幂)
安全性经过长期验证 对量子计算不免疫

4.3 ECC算法原理:椭圆曲线上的「轻骑兵」

ECC,椭圆曲线密码学。它比RSA年轻,但已经成为现代密码学的宠儿。为什么?因为同样的安全强度下,ECC的密钥更短。

举个例子:ECC-256(256位密钥)的安全性与RSA-3072相当。但ECC-256的公钥只有32字节,而RSA-3072的公钥是384字节。在MCU上,存储空间寸土寸金,ECC的优势很明显。

ECC的安全性基于椭圆曲线上的离散对数问题。说白了:给定曲线上两点G和Q,找到整数k使得Q = kG,非常难。这就是ECC的数学基础。

在安全启动中,ECC签名常用的是ECDSA算法。它的流程:

  • 签名:用私钥对哈希值生成一对数字(r, s)。
  • 验证:用公钥和签名(r, s)恢复出哈希值,与原始哈希比较。

我个人的习惯是,在资源受限的MCU上优先选ECC。比如一个只有64KB Flash的芯片,用RSA-2048光存公钥就要256字节,而ECC-256只要32字节。省下来的空间可以放更多功能代码。

关键点:ECC的曲线选择很重要。工业界最常用的是secp256r1(也叫P-256)。有些芯片支持硬件加速,比如NXP的LPC55xx系列。如果硬件不支持,软件实现ECDSA在Cortex-M4上大约需要200-500ms。

ECC的优缺点:

优点 缺点
密钥短,节省存储空间 算法相对复杂,实现容易出错
相同安全强度下计算量更小 硬件加速器不如RSA普及
适合资源受限的MCU 曲线参数选择需要谨慎(不要用自定义曲线)

4.4 实战对比:RSA vs ECC,怎么选?

好,现在你知道了两种算法。那在安全启动里,到底选哪个?

我给出一个简单的决策树:

  • 如果你的MCU有RSA硬件加速器(比如STM32L5系列),用RSA-2048。硬件加速下,验证时间可以做到10ms以内。
  • 如果你的MCU存储空间紧张(比如Flash只有32KB),用ECC-256。公钥小,签名也小(64字节 vs RSA的256字节)。
  • 如果你需要兼容现有PKI体系(比如公司已经部署了RSA证书),那就用RSA。别为了技术而技术。
  • 如果你追求未来安全性,可以考虑ECC。因为ECC对量子计算的抵抗力比RSA稍强(虽然都不免疫)。

我曾经在一个工业网关项目里,最初选了RSA-2048。但后来发现,网关需要存储100个设备的公钥。RSA-2048每个公钥256字节,100个就是25KB。换成ECC-256后,只要3.2KB。嗯,差距就是这么大。

小技巧:无论选RSA还是ECC,签名验证的代码一定要用常量时间实现。否则,攻击者可以通过侧信道攻击(比如功耗分析)提取私钥。我在做安全审计时,就见过因为没做常量时间而被打穿的产品。

4.5 哈希+签名:安全启动的完整链路

最后,我们把三个东西串起来。一个典型的安全启动验证流程:

1. 固件编译时:
   - 计算固件哈希 H = SHA256(firmware)
   - 用私钥对H签名,得到签名S
   - 将S附加到固件末尾

2. 设备启动时:
   - 读取固件,计算 H' = SHA256(firmware)
   - 读取公钥,验证签名S是否匹配H'
   - 如果验证通过,跳转到固件执行
   - 如果失败,进入错误处理(比如停止启动)

这个流程里,SHA-256保证固件完整性,RSA/ECC保证签名不可伪造。两者缺一不可。

嗯,到这里,公钥密码学的基础就讲完了。下一节,我们会深入安全启动的具体实现——如何把公钥烧录到OTP、如何设计启动加载器、以及如何应对物理攻击。到时候见。