密码学基础(上):对称加密与非对称加密、哈希函数、数字签名原理
各位好,欢迎来到第二章。说实话,密码学是固件安全的基石。你想想看,没有密码学,签名防篡改就是空中楼阁。今天咱们就把对称加密、非对称加密、哈希函数和数字签名这几个核心概念彻底讲透。
我刚开始做嵌入式安全那会儿,也踩过不少坑。有一次,我图省事直接用对称加密给固件签名——结果密钥被逆向出来,整个产品线都得紧急召回。从那以后,我再也不敢轻视密码学基础了。
2.1 对称加密:一把钥匙开一把锁
对称加密,说白了就是加密和解密用同一把密钥。就像你家的门锁,用同一把钥匙锁门和开门。
核心特点:速度快、效率高,适合加密大量数据。但密钥分发是个大难题。
我在项目中常用的对称加密算法有这些:
| 算法 | 密钥长度 | 分组大小 | 典型应用场景 |
|---|---|---|---|
| AES | 128/192/256 bit | 128 bit | 固件加密、存储加密 |
| ChaCha20 | 256 bit | 流加密 | 嵌入式设备、IoT |
| SM4 | 128 bit | 128 bit | 国密标准 |
举个实际例子。假设你要加密一段固件数据:
// AES-256-CBC 加密示例(伪代码)
uint8_t key[32] = {0x2b, 0x7e, 0x15, 0x16, ...};
uint8_t iv[16] = {0x00, 0x01, 0x02, ...};
uint8_t plaintext[] = "firmware_binary_v2.1";
uint8_t ciphertext[256];
aes_encrypt(key, iv, plaintext, ciphertext, AES_256_CBC);
// 解密时用同样的 key 和 iv
aes_decrypt(key, iv, ciphertext, decrypted, AES_256_CBC);
避坑指南:我曾经见过有人把密钥硬编码在固件里,结果被反编译直接提取。密钥必须存储在安全元件(SE)或硬件安全模块(HSM)中。
2.2 非对称加密:公钥私钥各司其职
非对称加密就聪明多了。它有一对密钥:公钥公开,私钥保密。公钥加密的数据只能用私钥解密,反过来私钥签名的数据可以用公钥验证。
为什么会这样?因为它是基于数学难题构造的,比如大整数分解或椭圆曲线离散对数问题。破解难度极高,但计算速度比对称加密慢得多。
我个人的习惯是:用非对称加密做密钥交换和数字签名,用对称加密做实际数据加密。两者配合,取长补短。
| 特性 | 对称加密 | 非对称加密 |
|---|---|---|
| 密钥数量 | 1个(共享密钥) | 2个(公钥+私钥) |
| 加密速度 | 快(硬件加速可达Gbps) | 慢(通常慢100-1000倍) |
| 密钥分发 | 困难(需要安全通道) | 容易(公钥可公开) |
| 典型算法 | AES, ChaCha20 | RSA, ECC, SM2 |
2.3 哈希函数:数据的数字指纹
哈希函数,你可以把它想象成数据的「数字指纹」。不管输入多大,输出都是固定长度。而且,哪怕只改一个比特,哈希值都会天翻地覆。
小技巧:我经常用哈希函数来校验固件完整性。下载完成后,计算哈希值,跟官方公布的比对。一致就说明没被篡改。
常见的哈希算法有:
- SHA-256:输出256位,目前最常用,安全性足够
- SHA-3:新一代标准,抗量子攻击潜力更好
- SM3:国密哈希算法,输出256位
- BLAKE2:速度比SHA-2快,适合嵌入式环境
哈希函数有三个核心特性:
- 抗原像性:给定哈希值,无法反推出原始数据
- 抗第二原像性:给定数据A,无法找到另一个数据B使得hash(A)=hash(B)
- 抗碰撞性:无法找到任意两个不同的数据有相同的哈希值
嗯,这里要注意:MD5和SHA-1已经被证明不安全了。我见过一些老项目还在用MD5做固件校验,结果被碰撞攻击轻松绕过。千万别再用它们了。
2.4 数字签名:防篡改的核心武器
数字签名,说白了就是「私钥签名,公钥验签」。它解决了三个问题:
- 完整性:数据有没有被改过?
- 真实性:数据是谁签的?
- 不可否认性:签名者不能抵赖
签名流程是这样的:
- 对固件计算哈希值
- 用私钥对哈希值加密(签名)
- 将签名附加到固件后面
- 验证时,用公钥解密签名得到哈希值A
- 重新计算固件哈希值B
- 比较A和B,一致则通过
// 数字签名验证伪代码
uint8_t firmware_hash[32];
sha256(firmware, firmware_len, firmware_hash);
uint8_t signature[256];
// 从固件尾部提取签名
extract_signature(firmware, &signature);
uint8_t decrypted_hash[32];
rsa_public_decrypt(public_key, signature, decrypted_hash);
if (memcmp(firmware_hash, decrypted_hash, 32) == 0) {
// 签名验证通过,固件未被篡改
boot_firmware();
} else {
// 签名验证失败,拒绝启动
enter_recovery_mode();
}
关键点:签名的是哈希值,不是整个固件。这样既保证了安全性,又避免了加密大文件带来的性能开销。
2.5 知识体系总览
为了让你更直观地理解这些概念之间的关系,我画了一张图:
2.6 实战中的选择建议
我根据多年经验,给你几个实用建议:
- 固件签名:用ECDSA(椭圆曲线数字签名算法),密钥短、速度快,适合嵌入式
- 固件加密:用AES-256-GCM,带认证加密,防篡改又防泄露
- 哈希校验:用SHA-256或SM3,别再用MD5
- 密钥存储:必须放在HSM或安全元件里,别放Flash
个人经验:我建议你在设计阶段就把密码学方案定下来。等产品量产了再想加签名,那成本可就大了去了。有一次我帮客户做安全审计,发现他们的Bootloader根本没验签——任何固件都能刷进去。嗯,那场面,简直了。
好了,这一章的内容就到这里。密码学基础是固件安全的根基,理解透了,后面的签名实战才能得心应手。