密码学基础回顾:哈希算法(SHA256)、非对称加密(RSA)、数字签名原理
各位同学,咱们今天聊点硬核的。做安全启动,密码学是绕不开的坎儿。我刚开始接触ATF移植那会儿,总觉得密码学是数学家的活儿,跟我一个搞嵌入式的有啥关系?后来被现实狠狠教育了一顿——不懂这些,你连签名验证的流程都看不懂,更别说自己动手移植了。
说白了,安全启动的核心就三件事:你是谁?你给的代码对不对?有没有人动过手脚? 这三个问题,正好对应我们今天要讲的三个知识点:哈希算法、非对称加密、数字签名。咱们一个一个来拆。
1. 哈希算法:代码的“指纹”
哈希算法,你可以把它想象成给一段数据生成一个独一无二的“身份证号”。不管你的数据是1KB还是1GB,经过哈希运算后,都会得到一个固定长度的摘要。这个摘要,就是数据的指纹。
在安全启动里,我们最常用的是SHA256。它输出的摘要长度是256位,也就是32字节。为什么是256位?嗯,这里要注意:位数越长,碰撞概率越低。SHA256目前还没人找到有效的碰撞方法,所以用在安全启动里是够用的。
哈希算法的两个核心特性:
- 单向性:从摘要反推原始数据,理论上不可能。你想想看,256位的摘要对应无限多种可能的输入,怎么可能反推回去?
- 抗碰撞性:找到两个不同数据,但哈希值相同,几乎不可能。我在项目中遇到过有人想用伪造的固件替换原厂固件,结果哈希值对不上,直接被安全启动拦下来了。
举个实际例子。你在ATF里配置安全启动时,经常要计算某个镜像的哈希值。比如这样:
# 计算BL2镜像的SHA256哈希值
openssl dgst -sha256 bl2.bin
# 输出:SHA256(bl2.bin)= a3f2b8c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1
这个哈希值,就是BL2镜像的“指纹”。后续验证时,只要重新计算一次,跟存储的指纹比对,就知道镜像有没有被篡改过。
我的个人习惯:在移植ATF时,我会先用Python脚本把各个镜像的哈希值算好,写到一个配置文件里。这样调试的时候,一眼就能看出哪个镜像出了问题。省得每次都要手动算一遍。
2. 非对称加密:RSA的前世今生
哈希算法能保证数据没被篡改,但它解决不了“你是谁”的问题。举个例子:你收到一个固件,哈希值是对的,但你怎么知道这个固件是官方发布的,而不是黑客伪造的?这时候就需要非对称加密登场了。
非对称加密,说白了就是一对钥匙:公钥和私钥。私钥自己藏着,公钥公开。用私钥加密的数据,只有对应的公钥能解开;反过来,用公钥加密的数据,只有对应的私钥能解开。
在安全启动里,我们用的是RSA算法。RSA的安全性基于一个数学难题:大整数分解。给你两个大素数p和q,乘起来得到n很容易,但给你n,让你分解出p和q,那就难了。我当年学密码学的时候,老师说过一句话我到现在还记得:“RSA的安全性,就建立在你算不过计算机的基础上。” 嗯,虽然现在量子计算有进展,但至少在嵌入式领域,RSA还是绝对的主流。
RSA的密钥长度通常有1024位、2048位、4096位。在ATF安全启动里,我建议至少用2048位。为什么?1024位在理论上已经被破解了,虽然实际攻击成本很高,但作为安全产品,咱们不能赌这个。
| 密钥长度 | 安全等级 | 适用场景 |
|---|---|---|
| 1024位 | 低(已不建议使用) | 老旧设备兼容 |
| 2048位 | 中(推荐) | 大多数嵌入式安全启动 |
| 4096位 | 高 | 高安全要求的金融、军工 |
我曾经踩过的坑:有一次移植ATF到一款低端芯片上,为了省存储空间,我用了1024位的RSA密钥。结果安全启动验证时,签名校验总是失败。查了半天才发现,芯片的硬件加速器只支持2048位以上的RSA运算。嗯,从那以后,我再也不敢在密钥长度上偷工减料了。
3. 数字签名:哈希+RSA的完美组合
哈希算法解决了完整性,RSA解决了身份认证。那数字签名,就是把这两者结合起来,同时解决两个问题。
数字签名的流程是这样的:
- 签名方(比如芯片厂商):先计算固件的哈希值,然后用私钥对这个哈希值进行加密,得到的结果就是“签名”。
- 验证方(比如你的设备):收到固件和签名后,先用同样的哈希算法计算固件的哈希值,然后用公钥解密签名,得到原始的哈希值。两个哈希值一比对,如果一致,说明固件是官方发布的,而且没被篡改过。
你想想看,这个流程是不是很巧妙?哈希保证了固件内容没变,RSA保证了签名确实来自持有私钥的官方。两者缺一不可。
在ATF里,数字签名通常用在BL1验证BL2、BL2验证BL31/BL32/BL33这个链条上。每个环节都要验签,形成一条信任链。这就是安全启动的核心思想。
ATF安全启动的签名验证流程(简化版):
1. BL1(ROM代码)内置了公钥
2. BL1从Flash读取BL2镜像及其签名
3. BL1计算BL2镜像的SHA256哈希值
4. BL1用公钥解密签名,得到原始哈希值
5. 比对两个哈希值:一致则跳转到BL2,不一致则死循环或报错
这个流程里,最关键的一步是公钥的存储。公钥必须放在不可篡改的存储介质里,比如一次性可编程存储器(OTP)或者ROM。如果公钥能被篡改,那整个安全体系就崩塌了。我在项目中见过有人把公钥放在Flash里,结果被黑客替换成自己的公钥,然后用自己的私钥签名恶意固件,安全启动形同虚设。这是个血的教训。
4. 知识体系总览
为了让你更直观地理解这三者的关系,我画了一张图。你可以看到,哈希算法和RSA是基础,数字签名是它们的应用。在安全启动里,这三者缺一不可。
从这张图你可以看到,整个体系是层层递进的。哈希和RSA是地基,数字签名是承重墙,安全启动是最终的建筑。地基不稳,房子就会塌。所以,我建议你在学习ATF移植之前,先把这三个概念吃透。
我的建议:如果你刚开始接触这些概念,不要急着看代码。先拿openssl命令行工具,自己手动做一遍签名和验签的流程。比如先生成一对RSA密钥,然后对一个文件签名,再验签。这个过程走一遍,比你读十遍理论都管用。
好了,这一章的内容就到这里。密码学基础是安全启动的基石,理解了这些,后面讲ATF的签名工具链、密钥管理、OTP配置等内容时,你就能跟上节奏了。