3. 密码学基础(上):对称加密(AES)、非对称加密(RSA/ECC)、哈希函数(SHA-256)
做安全启动,说白了就是解决三个问题:你是谁?你从哪里来?你要到哪里去?——开个玩笑。但认真讲,MCU 的启动链安全,核心就靠三种密码学工具:对称加密、非对称加密和哈希函数。
我刚开始接触 MCU 安全时,总觉得这些算法离嵌入式很远。直到有一次,我在一个 IoT 网关项目里,因为没选对哈希算法,导致启动时间多了 200ms,被客户怼了一顿。从那以后,我对这些基础算法再也不敢马虎了。
这一章,咱们就把这三类工具掰开揉碎,讲清楚它们各自在 MCU-Boot 里扮演什么角色。
3.1 对称加密:AES
对称加密,就是加密和解密用同一把钥匙。你想想看,就像你家大门,用一把钥匙锁上,也用同一把钥匙打开。在 MCU 启动场景里,我们常用它来加密固件镜像,防止别人直接读 Flash 就把代码抄走了。
3.1.1 AES 的核心参数
AES(Advanced Encryption Standard)是目前最主流的对称加密算法。在 MCU 上,我们最关心这几个参数:
| 参数 | 常见值 | 说明 |
|---|---|---|
| 密钥长度 | 128 / 192 / 256 bit | MCU-Boot 常用 AES-128,平衡安全与速度 |
| 分组大小 | 128 bit(固定) | AES 每次加密 16 字节 |
| 工作模式 | ECB / CBC / CTR / GCM | MCU 上推荐 GCM 或 CTR,避免 ECB 的弱点 |
| 填充方式 | PKCS7 / NoPadding | 流模式不需要填充 |
3.1.2 MCU 上的 AES 实现
大多数现代 MCU 都内置了 AES 硬件加速器。我个人习惯是:能用硬件就别用软件。硬件 AES 不仅快,还能防侧信道攻击。
下面是一个典型的硬件 AES 初始化代码(以 STM32 为例):
// 初始化 AES 硬件外设
HAL_AES_Init(&haes);
// 设置密钥(128位)
uint8_t key[16] = {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C};
// 设置初始向量(CBC模式需要)
uint8_t iv[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
// 加密一块数据
HAL_AES_Encrypt(&haes, plaintext, 16, ciphertext, HAL_AES_MODE_CBC);
3.2 非对称加密:RSA 与 ECC
非对称加密,就是加密和解密用不同的钥匙。一把公钥公开,一把私钥保密。在安全启动里,我们通常用私钥签名固件,用公钥验证签名。这样即使公钥被拿到,也无法伪造固件。
3.2.1 RSA:经典但沉重
RSA 的安全性基于大整数分解的难度。在 MCU 上,RSA 的主要问题是:计算量大,密钥长。
- 密钥长度:通常 2048 位起步,1024 位已被认为不安全
- 签名验证:比 ECC 慢 5-10 倍
- 内存占用:大数运算需要较多 RAM
我记得有一次在 Cortex-M4 上做 RSA-2048 签名验证,一次验证花了将近 800ms。对于启动时间要求 500ms 以内的产品,这显然不行。
3.2.2 ECC:轻量级选手
ECC(椭圆曲线密码学)在相同安全强度下,密钥更短,计算更快。比如:
| 安全等级 | RSA 密钥长度 | ECC 密钥长度 |
|---|---|---|
| 80 bit | 1024 | 160 |
| 112 bit | 2048 | 224 |
| 128 bit | 3072 | 256 |
| 192 bit | 7680 | 384 |
在 MCU-Boot 里,我个人强烈推荐使用 ECC-256(secp256r1)。它能在安全性和性能之间取得很好的平衡。
3.3 哈希函数:SHA-256
哈希函数,就是把任意长度的数据,压缩成一个固定长度的摘要。而且这个摘要是不可逆的——你没法从摘要反推出原始数据。
在安全启动里,哈希函数有三个关键用途:
- 完整性校验:计算固件的哈希值,和存储的参考值对比,看固件有没有被篡改
- 数字签名的基础:先对固件做哈希,再对哈希值做签名,而不是直接对固件签名
- 密钥派生:从主密钥派生出多个子密钥
3.3.1 SHA-256 的特点
- 输出长度:256 位(32 字节)
- 安全强度:128 位(抗碰撞)
- 硬件支持:很多 MCU 内置 SHA-256 硬件加速器
你想想看,为什么我们不直接对固件签名?因为固件可能很大(几 MB),非对称签名算法处理大块数据很慢。先做哈希,把固件压缩成 32 字节,再对这 32 字节签名,效率就高多了。
3.3.2 哈希链在安全启动中的应用
在 MCU-Boot 里,我们经常用哈希链来验证多级启动。比如:
BootROM → Bootloader → 应用固件
↓ ↓ ↓
验证BL哈希 验证APP哈希 运行
每一级启动前,先计算下一级固件的 SHA-256 值,和签名中提取的哈希值比对。一致才跳转执行。
3.4 三种工具如何协同工作
好了,现在我们把三种工具串起来,看看在安全启动里它们是怎么配合的:
- AES:加密固件,防止泄露
- ECC/RSA:签名验证,防止篡改
- SHA-256:完整性校验,压缩数据
嗯,这一章的内容就到这儿。记住:密码学不是数学题,而是工程实践。选对算法、配好参数、用好硬件加速,你的 MCU-Boot 才能既安全又高效。