密码学基础(上):对称加密与非对称加密、哈希函数(SHA-256)、消息认证码(HMAC)
各位同学,欢迎来到第二章。上一章我们聊了安全启动的整体框架,说白了就是「信任链」怎么建立。但信任链的每个环节,都离不开密码学这把锁。今天我们就来拆解一下,安全启动里最常用的几个密码学工具。
我个人习惯把密码学比作工具箱。你不需要成为密码学家,但你必须知道每个工具是干什么的、什么时候用、用错了会出什么事故。我在项目里见过太多「工具用对但参数配错」的翻车现场了。
2.1 对称加密:一把钥匙开一把锁
对称加密,顾名思义,加密和解密用的是同一把密钥。就像你家的门锁,用同一把钥匙锁门和开门。
在嵌入式世界里,最常用的对称加密算法是 AES(Advanced Encryption Standard)。AES 有 128、192、256 位三种密钥长度。安全启动里,我们通常用 AES-128 或 AES-256。
核心要点:对称加密速度快,适合加密大量数据。但密钥分发是个大麻烦——你怎么把密钥安全地交给对方?
我曾经在一个 IoT 项目里,看到有人把 AES 密钥硬编码在固件里。嗯,结果可想而知,固件被反编译后,密钥直接暴露。所以对称加密虽然快,但密钥管理才是真正的难点。
AES 的工作模式
AES 本身只处理 128 位的数据块。要加密任意长度的数据,就需要工作模式。安全启动里最常见的是 ECB 和 CBC 模式。
| 模式 | 特点 | 安全启动中的使用 |
|---|---|---|
| ECB | 每个块独立加密,相同明文得到相同密文 | 不推荐,有模式泄露风险 |
| CBC | 每个块与前一个密文异或后再加密 | 常用,但需要 IV(初始化向量) |
| CTR | 将计数器加密后与明文异或 | 可并行,适合高性能场景 |
避坑指南:我曾经接手过一个项目,ECB 模式加密固件镜像。攻击者只需要观察密文块重复模式,就能推断出固件的结构信息。所以,安全启动里千万别用 ECB。
2.2 非对称加密:公钥和私钥的默契
非对称加密解决了密钥分发的难题。它使用一对密钥:公钥可以公开,私钥必须保密。用公钥加密的数据,只能用私钥解密;反之亦然。
安全启动里,非对称加密主要用于签名验证。设备出厂时烧录公钥,固件发布时用私钥签名。启动时,设备用公钥验证固件签名是否合法。
最常用的算法是 RSA 和 ECC(椭圆曲线密码学)。
| 算法 | 密钥长度 | 安全强度 | 计算开销 |
|---|---|---|---|
| RSA | 2048 位 | 高 | 较大(尤其签名验证) |
| ECC | 256 位(P-256) | 高 | 较小,适合资源受限设备 |
我个人更倾向于在嵌入式设备上用 ECC。为什么?因为 256 位的 ECC 密钥就能达到 2048 位 RSA 的安全强度,而且签名验证速度更快。你想想看,在只有几百 KB Flash 的 MCU 上,省下的每一字节都很珍贵。
经验之谈:我在一个车载项目里,用 ECC P-256 做签名验证。整个验证流程只需要 50ms 左右,而如果用 RSA 2048,可能要 200ms 以上。启动时间对汽车来说很敏感,所以 ECC 是更好的选择。
2.3 哈希函数:数据的指纹
哈希函数能把任意长度的数据,压缩成固定长度的摘要。这个摘要就像数据的「指纹」——内容变了,指纹一定变。
安全启动里,哈希函数有两个核心用途:
- 完整性校验:计算固件的哈希值,与预期值对比,判断固件是否被篡改。
- 数字签名的预处理:先对固件做哈希,再对哈希值签名,而不是直接对固件签名。
我们最常用的是 SHA-256,输出 256 位(32 字节)的摘要。
// SHA-256 示例(伪代码)
uint8_t firmware_data[] = { ... }; // 固件数据
uint8_t hash_output[32]; // 存放哈希结果
sha256_context_t ctx;
sha256_init(&ctx);
sha256_update(&ctx, firmware_data, sizeof(firmware_data));
sha256_final(&ctx, hash_output);
// 现在 hash_output 就是固件的指纹
// 与预期值比较,判断完整性
if (memcmp(hash_output, expected_hash, 32) == 0) {
// 固件完整
} else {
// 固件被篡改
}
重要提醒:哈希函数是单向的。你不能从哈希值反推出原始数据。所以哈希只能用来验证完整性,不能用来加密。
我记得有一次,同事问我:「能不能用 SHA-256 加密固件?」我差点没噎住。哈希不是加密,它没有密钥,也没有解密过程。这个混淆很常见,但一定要分清。
2.4 消息认证码:给数据加个防伪标签
哈希函数只能检测数据是否被篡改,但不能验证数据是否来自合法的发送方。这时候就需要 消息认证码(MAC) 了。
MAC 使用一个共享密钥,对数据计算一个认证标签。只有拥有相同密钥的双方,才能验证这个标签。最常用的 MAC 算法是 HMAC(Hash-based Message Authentication Code)。
HMAC 的公式是:
HMAC(K, m) = H( (K' ⊕ opad) || H( (K' ⊕ ipad) || m ) )
其中:
- K 是密钥
- m 是消息
- H 是哈希函数(如 SHA-256)
- opad 和 ipad 是固定的填充值
说白了,HMAC 就是「带密钥的哈希」。它既能保证完整性,又能保证真实性。
实战场景:在安全启动的某些实现中,我们会在固件头部附加一个 HMAC 标签。启动时,设备用预置的密钥重新计算 HMAC,与标签对比。这样既能防止固件被篡改,也能防止非授权方生成合法固件。
2.5 知识体系总览
下面这张图,把本章的核心知识点串起来了。你可以把它当作一个快速参考。
2.6 本章小结
这一章我们覆盖了四个核心概念:
- 对称加密:速度快,适合加密大量数据,但密钥分发是痛点。AES-CBC 是安全启动的常用选择。
- 非对称加密:解决了密钥分发问题,主要用于签名验证。ECC 比 RSA 更适合嵌入式设备。
- 哈希函数:数据的指纹,用于完整性校验。SHA-256 是行业标准。
- 消息认证码:带密钥的哈希,同时保证完整性和真实性。HMAC 是最常见的实现。