3. 密码学基础回顾:对称加密、非对称加密与哈希函数在嵌入式中的应用

做嵌入式安全,说白了就是跟密码学打交道。你想想看,CAN升级也好,OTA远程升级也罢,核心就三件事:数据不能被偷看、数据不能被篡改、数据来源要可信。这三件事分别对应加密、完整性校验和身份认证。

我个人习惯把密码学工具分成三类:对称加密、非对称加密和哈希函数。别被这些术语吓到,咱们一个一个拆开讲。

3.1 对称加密:AES-128/256

对称加密,说白了就是加密和解密用同一把钥匙。就像你家的门锁,用钥匙锁上,再用同一把钥匙打开。在嵌入式里,最常用的就是AES。

AES 核心参数

  • 密钥长度:128位、192位、256位。我建议至少用128位,资源够的话直接上256位。
  • 分组大小:固定128位(16字节)。
  • 工作模式:ECB、CBC、CTR、GCM等。千万别用ECB,我在项目里见过有人用ECB加密固件,结果被直接破解了。

我在项目中遇到过一件事:有个同事用AES-128加密固件,但用的是ECB模式。结果呢?攻击者通过分析密文块的重现规律,直接还原了部分固件内容。嗯,从那以后我强制团队只用CBC或GCM模式。

我的建议:OTA升级场景下,优先用AES-256-GCM。GCM模式自带认证标签,能同时保证机密性和完整性,省掉额外算哈希的步骤。

代码示例(伪代码,展示核心逻辑):

// AES-256-CBC 加密示例
uint8_t key[32] = {0x2b, 0x7e, ...};  // 256位密钥
uint8_t iv[16]  = {0x00, 0x01, ...};  // 初始化向量

// 加密固件块
aes_cbc_encrypt(key, iv, plaintext, ciphertext, length);

// 解密固件块
aes_cbc_decrypt(key, iv, ciphertext, plaintext, length);

避坑指南:我曾经见过有人把IV写死在代码里。这是大忌!IV必须每次随机生成,否则攻击者可以通过IV重用破解你的加密。

3.2 非对称加密:RSA与ECC

非对称加密,加密和解密用不同的钥匙。一把公钥公开,一把私钥自己藏着。公钥加密的数据只能用私钥解密,反过来私钥签名可以用公钥验证。

在嵌入式里,非对称加密主要干两件事:数字签名和密钥交换。OTA升级里,我们用它来签名固件,确保固件是官方发布的。

算法 密钥长度 安全强度 嵌入式开销
RSA-2048 2048位 112位等效 高(签名慢,验签快)
RSA-4096 4096位 128位等效 非常高
ECC-256 256位 128位等效 低(签名快,验签快)
ECC-384 384位 192位等效 中等

你想想看,RSA-2048的密钥长度是2048位,而ECC-256只需要256位就能达到相同的安全强度。在资源受限的MCU上,ECC的优势非常明显。我个人习惯在STM32这类Cortex-M4/M7芯片上用ECC-256,签名验签速度能快3-5倍。

为什么ECC更适合嵌入式?

  • 密钥更短,节省存储空间
  • 计算更快,尤其是签名操作
  • 功耗更低,适合电池供电设备

我曾经在一个项目中用RSA-2048做固件签名,结果每次签名要等好几秒,用户升级体验极差。后来换成ECC-256,签名时间降到几百毫秒,问题迎刃而解。

3.3 哈希函数:SHA-256

哈希函数,说白了就是给数据算一个「指纹」。不管数据多大,算出来的哈希值长度固定。而且,哪怕只改一个比特,哈希值都会完全不一样。

在嵌入式里,SHA-256是最常用的哈希算法。它输出256位(32字节)的哈希值,碰撞概率极低,可以放心使用。

哈希函数的三大用途

  1. 完整性校验:计算固件的哈希值,跟官方发布的哈希值对比,看固件有没有被篡改。
  2. 数字签名:先对固件算哈希,再对哈希值签名。这样签名速度快,而且能覆盖整个固件。
  3. 密钥派生:用HKDF(基于HMAC的密钥派生函数)从主密钥派生出多个子密钥。

代码示例:

// SHA-256 哈希计算
uint8_t hash[32];
sha256_context ctx;

sha256_init(&ctx);
sha256_update(&ctx, firmware_data, firmware_length);
sha256_final(&ctx, hash);

// 对比哈希值
if (memcmp(hash, expected_hash, 32) == 0) {
    // 固件完整,可以升级
} else {
    // 固件被篡改,拒绝升级
}

避坑指南:我曾经见过有人只用CRC32做固件完整性校验。CRC32是检错码,不是密码学哈希,攻击者可以轻松构造出相同CRC32的恶意固件。记住,安全场景必须用SHA-256或更强的哈希函数。

3.4 三种工具如何配合使用?

在实际的OTA升级方案中,这三种工具不是孤立使用的,而是配合起来形成一套完整的安全体系。下面这张图展示了它们的协作关系:

密码学工具在OTA升级中的协作关系 密码学工具在OTA升级中的协作关系 原始固件 SHA-256 哈希 ECC 私钥签名 固件包 + 签名 + 哈希值 AES-256 加密 流程说明 1. 先算固件哈希 2. 用私钥签哈希 3. 打包后加密传输 4. 设备端反向验证

整个流程是这样的:

  1. 哈希:先对原始固件算SHA-256哈希值,得到32字节的「指纹」。
  2. 签名:用ECC私钥对这个哈希值签名,生成签名数据。
  3. 打包:把固件、签名、哈希值打包成一个升级包。
  4. 加密:用AES-256对整个升级包加密,防止传输过程中被窃听。

设备端收到升级包后,反向操作:先解密,再验签,最后对比哈希值。全部通过才允许升级。

为什么先哈希再签名?

直接对固件签名也可以,但固件可能很大(几MB甚至几十MB),签名算法处理大块数据很慢。先哈希再签名,签名算法只需要处理32字节的哈希值,速度快得多。而且,哈希值能代表整个固件,效果是一样的。

3.5 嵌入式环境下的选型建议

最后,我根据实际项目经验,给出一份选型建议表:

场景 推荐算法 理由
固件加密传输 AES-256-GCM 一次搞定加密+完整性校验
固件签名 ECC-256 (secp256r1) 密钥短、速度快、安全性高
完整性校验 SHA-256 标准、稳定、硬件加速支持好
密钥交换 ECDH (基于ECC) 前向安全性好,适合嵌入式
随机数生成 硬件TRNG + DRBG 真随机数,安全基础

我的经验:很多MCU(比如STM32、NXP i.MX RT系列)都内置了硬件加密引擎,支持AES、SHA、RSA、ECC等算法的硬件加速。一定要用硬件加速!纯软件实现AES-256加密1MB固件可能要几秒钟,硬件加速只需要几十毫秒。

嗯,密码学基础就讲到这里。这些工具是后面所有安全方案的地基,理解透了,后面的内容就顺了。