密码学基础(上):对称加密与非对称加密、哈希函数、数字签名
各位同学,咱们今天聊点硬核的。密码学这东西,听起来高大上,其实说白了就是「锁」和「钥匙」的学问。做固件安全,不懂密码学,就像造保险柜却不知道锁芯长啥样——迟早要翻车。
我刚开始接触嵌入式安全时,也踩过不少坑。有一次给一个IoT设备做固件升级,觉得「反正数据量不大,随便加密一下就行」,结果被客户的安全审计直接打回。从那以后,我老老实实把密码学基础补了一遍。今天这堂课,就是帮你把地基打牢。
1. 对称加密:一把钥匙开一把锁
对称加密,顾名思义,加密和解密用的是同一把密钥。就像你家大门钥匙——你自己能用,你老婆也能用,谁拿着谁就能开门。
常见的对称加密算法有 AES(Advanced Encryption Standard)、DES(已淘汰)、SM4(国密标准)。AES 是目前嵌入式领域的主流选择,密钥长度支持 128、192、256 位。
核心要点:对称加密速度快,适合大量数据加密。但密钥分发是个大麻烦——你怎么把密钥安全地交给对方?
我在一个智能门锁项目里用过 AES-128。当时需要把固件包加密后通过蓝牙传输给门锁,解密后写入 Flash。嗯,这里要注意:AES 的密钥必须存储在安全区域(比如芯片内部的 eFuse 或 TEE),绝对不能硬编码在普通代码里。我曾经见过一个产品,密钥直接写在全局变量里,反编译一下就能看到——这跟没锁门有什么区别?
AES 工作模式对比
| 模式 | 特点 | 适用场景 |
|---|---|---|
| ECB | 简单,但相同明文块产生相同密文块 | 不推荐,有安全风险 |
| CBC | 需要 IV,密文块依赖前一块 | 固件加密常用 |
| GCM | 同时提供加密和认证 | 通信加密首选 |
我个人习惯用 GCM 模式,因为它自带认证标签,能检测数据是否被篡改。省掉单独算 MAC 的步骤,代码也干净一些。
2. 非对称加密:公钥私钥,各司其职
非对称加密就不一样了。它有一对密钥:公钥(Public Key)和私钥(Private Key)。公钥可以公开,私钥必须保密。用公钥加密的数据,只有对应的私钥能解密;反过来,用私钥签名的数据,公钥可以验证。
你想想看,这解决了什么问题?密钥分发!你不需要把私钥传给任何人,只需要把公钥公开。别人用你的公钥加密数据,只有你能解密。
嵌入式里最常用的非对称算法是 RSA 和 ECC(椭圆曲线密码学)。RSA 密钥长度通常 2048 位起步,ECC 用 256 位就能达到同等安全强度。ECC 的优势在于密钥短、计算快,特别适合资源受限的 MCU。
我的经验:在 Cortex-M4 上做 RSA-2048 签名验证,大概需要几十毫秒;而 ECDSA 用 P-256 曲线,只需要几毫秒。如果你的芯片没有硬件加速器,优先选 ECC。
3. 哈希函数:数据的「指纹」
哈希函数能把任意长度的数据,压缩成固定长度的摘要(Digest)。而且这个摘要是唯一的——哪怕只改一个比特,摘要都会完全不一样。哈希是单向的,你没法从摘要反推出原始数据。
SHA-256 是目前最通用的哈希算法,输出 256 位(32 字节)的摘要。在固件签名里,我们通常先对固件算 SHA-256,再对摘要做签名。这样既保证了完整性,又提高了签名效率——毕竟签名 32 字节比签名几兆固件快得多。
避坑指南:我曾经遇到过一个案例,工程师用 MD5 做固件校验。MD5 已经被证明存在碰撞攻击,攻击者可以构造两个不同固件但 MD5 相同的文件。结果就是:固件被篡改了,校验却通过了。所以,别再用 MD5 和 SHA-1 了,老老实实用 SHA-256。
常见哈希算法对比
| 算法 | 输出长度 | 安全性 | 推荐度 |
|---|---|---|---|
| MD5 | 128 位 | 已破解 | ❌ 不推荐 |
| SHA-1 | 160 位 | 已破解 | ❌ 不推荐 |
| SHA-256 | 256 位 | 安全 | ✅ 推荐 |
| SHA-3 | 可变 | 安全 | ✅ 可选 |
4. 数字签名:证明「你是谁」和「没被改过」
数字签名是非对称加密和哈希函数的组合应用。它的核心作用有两个:身份认证和完整性校验。
流程是这样的:
- 发送方对固件算 SHA-256,得到摘要 H
- 发送方用私钥对 H 签名,得到签名值 S
- 发送方把固件 + S 一起发给接收方
- 接收方用公钥验证 S,得到摘要 H1
- 接收方对固件算 SHA-256,得到摘要 H2
- 如果 H1 == H2,说明固件没被改过,且确实是私钥持有者签的
RSA 和 ECDSA 是两种主流的签名算法。RSA 签名验证只需要公钥,计算量相对小;ECDSA 签名速度快,密钥短。在固件启动链里,通常用 ECDSA 做签名,因为 BootROM 里空间有限,ECC 的代码量更小。
关键点:签名 ≠ 加密。签名不隐藏数据,只保证数据来源和完整性。如果你既要保密又要防篡改,那就先加密再签名,或者用签密方案。
5. 知识体系总览
下面这张图,把今天讲的核心概念串起来了。你仔细看一遍,应该能理解它们之间的关系。
6. 实战中的选择建议
做固件签名时,我一般这样选型:
- BootROM 验签:用 ECDSA P-256,代码量小,速度快
- 固件加密传输:用 AES-256-GCM,兼顾加密和认证
- 固件完整性校验:用 SHA-256,配合签名一起用
- 密钥存储:私钥放安全元件或 eFuse,公钥可以公开
一个小技巧:在开发阶段,可以用 OpenSSL 命令行生成密钥对和签名,方便调试。等产品定型了,再换成硬件安全模块(HSM)管理私钥。
好了,今天的内容就到这里。密码学基础是固件安全的基石,你把这些概念吃透了,后面讲启动链防篡改时,就会觉得顺理成章。记住一句话:别自己发明密码算法,用标准库,用成熟方案。这是无数前辈用血泪换来的教训。