2、密码学基础(上):哈希函数(SHA-256)、数字签名(RSA/ECDSA)、公钥基础设施(PKI)
各位同学,欢迎来到密码学基础的上半部分。这部分内容,是理解安全启动和Verified Boot的基石。说白了,没有这些数学工具,后面所有的安全机制都无从谈起。我个人习惯把这一章叫做“信任的起点”,因为从哈希到签名再到PKI,每一步都在回答一个核心问题:我们凭什么相信这段代码是可信的?
2.1 哈希函数:数据的“指纹”
先聊聊哈希函数。你想想看,我们要验证一个几兆甚至几十兆的固件镜像,总不能把整个文件都拿去比对签名吧?那效率太低了。哈希函数就是来解决这个问题的。
它能把任意长度的数据,映射成一个固定长度的、看似随机的字符串。这个字符串,就是数据的“指纹”。
哈希函数有几个关键特性,我重点说一下:
- 单向性:从哈希值反推原始数据,在计算上是不可行的。嗯,这一点很重要,保证了你的固件哈希值泄露了,攻击者也拿不到你的固件内容。
- 抗碰撞性:找到两个不同的输入,使得它们的哈希值相同,这在计算上是极其困难的。我曾经在项目中遇到过有人质疑SHA-256的安全性,说万一碰撞了怎么办?我当时的回答是:理论上存在,但以目前的算力,你找到一组碰撞的时间,比宇宙的年龄还长。
- 雪崩效应:输入哪怕只改变一个比特,输出的哈希值也会发生天翻地覆的变化。这个特性在检测固件是否被篡改时特别有用。
在安全启动中,我们最常用的是 SHA-256。它输出256比特(32字节)的哈希值。为什么是256?因为它在安全性和性能之间取得了很好的平衡。我记得早期有些嵌入式设备还在用SHA-1,后来因为碰撞攻击被证明可行,大家就都迁移到SHA-256了。
核心要点:哈希函数不是加密。加密可以解密,哈希不行。它是单向的、不可逆的。在安全启动流程中,我们通常先计算固件的SHA-256哈希值,然后对这个哈希值进行签名,而不是对整个固件签名。
2.2 数字签名:证明“你是谁”和“你没被改过”
哈希函数解决了“完整性”问题,但没解决“真实性”问题。也就是说,你拿到了一个固件,算出了它的哈希值,但你不知道这个固件到底是谁发布的。数字签名就是来解决这个问题的。
数字签名基于非对称加密。简单说,就是一对密钥:私钥(自己保管,打死也不能给别人)和公钥(公开的,谁都可以拿)。
签名过程是这样的:
- 发布者用私钥对固件的哈希值进行加密,生成签名。
- 发布者把固件和签名一起发出去。
- 验证者拿到固件和签名后,用发布者的公钥解密签名,得到哈希值A。
- 验证者自己计算固件的哈希值B。
- 如果A等于B,说明固件确实是发布者签发的,而且没有被篡改过。
目前主流的签名算法有两种:RSA 和 ECDSA。
| 特性 | RSA | ECDSA |
|---|---|---|
| 安全性基础 | 大整数分解难题 | 椭圆曲线离散对数难题 |
| 密钥长度 | 较长(如2048位、4096位) | 较短(如256位即可达到同等安全强度) |
| 签名速度 | 验证快,签名慢 | 签名快,验证慢 |
| 典型应用 | 传统PC、服务器 | 嵌入式设备、移动设备 |
我个人在嵌入式项目中更偏爱ECDSA。为什么?因为嵌入式设备的CPU性能有限,而ECDSA可以用更短的密钥达到同样的安全级别,节省了宝贵的存储空间和计算时间。我曾经在一个资源受限的IoT设备上,用RSA-2048做签名验证,结果启动时间硬生生多了两秒。后来换成ECDSA P-256,问题就解决了。
避坑指南:我曾经见过有人把私钥硬编码在固件里,美其名曰“方便测试”。这是绝对不允许的!私钥一旦泄露,整个安全体系就崩塌了。私钥必须存储在安全硬件中,比如HSM(硬件安全模块)或者安全芯片的OTP(一次性可编程)区域。
2.3 公钥基础设施(PKI):信任的链条
好,现在你有了一对密钥。但问题来了:你怎么知道某个公钥确实属于某个发布者?比如,你从网上下载了一个固件,它附带了一个公钥,你怎么确定这个公钥不是攻击者伪造的?
这就是PKI要解决的问题。PKI说白了,就是一套管理公钥的体系,它通过数字证书和证书颁发机构(CA)来建立信任。
PKI的核心组件:
- 证书颁发机构(CA):一个可信的第三方,负责签发和管理数字证书。你可以把它理解成“网络世界的公安局”。
- 数字证书:一个电子文档,把公钥和持有者的身份信息绑定在一起。证书里包含了持有者的公钥、名称、有效期、CA的签名等信息。
- 证书链:从根CA证书开始,到中间CA证书,最后到终端实体证书的一条信任路径。你想想看,如果每个设备都信任同一个根CA,那么只要根CA是安全的,整个链条就是安全的。
在安全启动中,PKI的应用非常典型。比如,你的设备出厂时,会预置一个根CA的公钥(通常烧死在芯片的OTP区域,不可更改)。然后,每次固件更新时,固件发布者会用私钥对固件签名,并附上自己的证书链。设备启动时,会用预置的根CA公钥去验证证书链,再用证书链中的公钥去验证固件签名。
注意:根CA公钥的存储是安全启动的“信任锚点”。一旦这个锚点被攻破,整个安全体系就完了。所以,根CA公钥必须存储在硬件保护的区域内,比如安全芯片的eFuse或OTP中,并且要确保在设备生命周期内不可更改。
嗯,这里还要提一下证书吊销。如果某个私钥泄露了,或者某个CA不再可信了,怎么办?PKI提供了证书吊销列表(CRL)和在线证书状态协议(OCSP)来撤销证书。但在嵌入式设备中,由于网络连接和存储空间的限制,证书吊销的实现往往比较困难。我建议在设计安全启动方案时,提前考虑好证书的更新和吊销机制,否则一旦出现问题,你可能会面临大规模设备需要召回的风险。
好了,这一章的内容就到这里。哈希函数、数字签名、PKI,这三者环环相扣,构成了安全启动的信任基础。下一章,我们会深入探讨这些密码学工具在安全启动流程中的具体应用。到时候,你会发现,原来这些看似抽象的概念,在真实的硬件启动过程中,每一步都至关重要。