密码学基础回顾:哈希算法、非对称加密与数字签名
各位好,欢迎来到第二章。在正式开始讲可信启动之前,咱们得先把密码学这块地基夯实了。你想想看,如果连签名是怎么签的、验签是怎么验的都不清楚,后面调试起 Secure Boot 来,那真是两眼一抹黑。
我个人习惯,在接触任何安全方案之前,先花半小时把涉及的密码学原语过一遍。不是为了让你成为密码学家,而是为了在出问题时,你能准确判断是算法选型错了,还是实现有 bug,还是密钥没管好。
这一章我们就聚焦三个核心概念:哈希算法、非对称加密(RSA 和 ECC)以及数字签名。这些都是可信启动的基石,一个都跑不掉。
2.1 哈希算法:数据的「指纹」
哈希算法,说白了就是一个单向函数。你给它任意长度的数据,它给你一个固定长度的摘要。这个摘要就像数据的指纹,只要原始数据改了一个比特,摘要就会面目全非。
在可信启动里,哈希算法主要干两件事:
- 完整性校验:验证固件在传输或存储过程中有没有被篡改。
- 签名预处理:对固件先做哈希,再对哈希值签名。这样签名速度快,而且能处理任意大小的固件。
目前业界最常用的哈希算法是 SHA-256。它输出 256 位(32 字节)的摘要,安全性足够,性能也均衡。
核心特性:
- 单向性:从摘要反推原始数据,计算上不可行。
- 抗碰撞性:找到两个不同数据产生相同摘要,计算上不可行。
- 雪崩效应:输入微小变化,输出变化巨大。
我在项目中遇到过一个问题:某款芯片的硬件哈希加速器只支持 SHA-1,但客户要求用 SHA-256。没办法,最后只能用软件实现 SHA-256,启动时间多了 200 毫秒。所以选型时一定要确认硬件支持哪些算法。
实战建议:
在固件签名流程中,建议对固件镜像做两次哈希:一次在签名前(计算待签名摘要),一次在签名后(计算整个签名包的完整性校验值)。这样可以隔离签名验证和镜像完整性验证的逻辑。
2.2 非对称加密:公钥与私钥
非对称加密,也叫公钥密码学。它使用一对密钥:私钥(必须保密)和公钥(可以公开)。用私钥加密的数据,只能用对应的公钥解密;反之亦然。
在可信启动场景里,我们主要用非对称加密来做数字签名,而不是数据加密。因为固件通常是明文存储和执行的,我们关心的是它的来源真实性和完整性,而不是机密性。
目前主流的两大算法是 RSA 和 ECC(椭圆曲线密码学)。
| 对比维度 | RSA | ECC |
|---|---|---|
| 安全性基础 | 大整数分解 | 椭圆曲线离散对数 |
| 密钥长度(等效 128 位安全) | 3072 位 | 256 位 |
| 签名速度 | 较慢(尤其私钥操作) | 较快 |
| 验签速度 | 较快 | 较慢 |
| 硬件资源消耗 | 高(大数运算) | 低(适合嵌入式) |
| 典型应用 | 传统 Secure Boot、代码签名 | IoT 设备、资源受限平台 |
我个人更倾向于在资源受限的嵌入式设备上使用 ECC,尤其是 ECDSA(椭圆曲线数字签名算法)。它的密钥短、签名短,对 Flash 和 RAM 都友好。但要注意,ECC 的验签比 RSA 慢,如果你的设备需要频繁验签(比如 OTA 升级),这个因素要考虑进去。
避坑指南:
我曾经在一个项目里直接用了 OpenSSL 生成的 RSA 2048 位密钥,没注意私钥格式。结果 BootROM 只支持 PKCS#1 格式,而我生成的是 PKCS#8。折腾了两天才发现是格式不匹配。所以,一定要提前确认 BootROM 或安全固件支持的密钥格式和算法参数。
2.3 数字签名:签名与验签流程
数字签名是非对称加密的典型应用。它解决了三个问题:
- 身份认证:确认签名者身份。
- 完整性:确认数据未被篡改。
- 不可否认性:签名者不能否认自己的签名行为。
在可信启动中,签名流程通常是这样的:
- 计算摘要:对固件镜像做 SHA-256 哈希,得到 32 字节的摘要。
- 签名:用私钥对摘要进行签名,生成签名值。
- 打包:将固件镜像、签名值、公钥证书(或公钥哈希)打包成一个签名固件包。
- 分发:将签名固件包烧录或通过网络下发到设备。
验签流程则是反过来:
- 提取:从固件包中提取固件镜像、签名值和公钥。
- 计算摘要:对固件镜像做 SHA-256 哈希。
- 验签:用公钥对签名值进行解密,得到原始摘要;与计算出的摘要比对。
- 判断:如果一致,验签通过;否则拒绝启动。
嗯,这里要注意:验签时比对的是摘要,而不是整个固件。所以哈希算法的安全性直接决定了整个签名体系的安全性。
关键点:
签名是对摘要签名,不是对原始数据签名。这样做的好处是:
- 签名速度快(摘要只有几十字节)。
- 签名值固定长度(与固件大小无关)。
- 可以灵活选择哈希算法和签名算法组合。
2.4 知识体系总览
为了让你更直观地理解这三者之间的关系,我画了一张图。你可以把它当作本章的知识地图。
2.5 实战中的算法选型建议
说了这么多理论,最后给点实在的。在可信启动项目中,算法选型通常要考虑以下几个因素:
- 硬件加速支持:优先使用芯片自带的硬件加速器,性能好、功耗低。我见过不少项目因为没用好硬件加速,导致启动时间超标。
- 密钥存储安全:私钥必须存储在安全区域(如 eFuse、OTP、HSM)。千万不要把私钥放在 Flash 里,那等于把家门钥匙放在门口垫子下。
- 算法强度与性能平衡:对于启动时间敏感的场合,可以考虑 ECDSA 搭配 SHA-256。对于安全等级要求极高的场合,RSA 4096 位仍然是稳妥选择。
- 证书链管理:不要只用单级签名,建议使用根证书 + 中间证书的链式结构。这样即使中间证书泄露,根证书还在,可以吊销和轮换。
我的经验:
在选型阶段,我建议你做一个简单的性能测试:在目标芯片上跑 100 次签名和 1000 次验签,记录时间。这样你就能拿到真实数据,而不是靠数据手册上的理论值做决策。我曾经被数据手册坑过一次,上面写 ECDSA 验签只要 5ms,实际跑出来 15ms。嗯,从那以后我再也不信纸面数据了。