密码学基础(上):对称加密与非对称加密、哈希函数、数字签名原理

各位好,欢迎来到第二章。说实话,密码学是固件安全的基石。你想想看,没有密码学,签名防篡改就是空中楼阁。今天咱们就把对称加密、非对称加密、哈希函数和数字签名这几个核心概念彻底讲透。

我刚开始做嵌入式安全那会儿,也踩过不少坑。有一次,我图省事直接用对称加密给固件签名——结果密钥被逆向出来,整个产品线都得紧急召回。从那以后,我再也不敢轻视密码学基础了。

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快,适合嵌入式环境

哈希函数有三个核心特性:

  1. 抗原像性:给定哈希值,无法反推出原始数据
  2. 抗第二原像性:给定数据A,无法找到另一个数据B使得hash(A)=hash(B)
  3. 抗碰撞性:无法找到任意两个不同的数据有相同的哈希值

嗯,这里要注意:MD5和SHA-1已经被证明不安全了。我见过一些老项目还在用MD5做固件校验,结果被碰撞攻击轻松绕过。千万别再用它们了。

2.4 数字签名:防篡改的核心武器

数字签名,说白了就是「私钥签名,公钥验签」。它解决了三个问题:

  • 完整性:数据有没有被改过?
  • 真实性:数据是谁签的?
  • 不可否认性:签名者不能抵赖

签名流程是这样的:

  1. 对固件计算哈希值
  2. 用私钥对哈希值加密(签名)
  3. 将签名附加到固件后面
  4. 验证时,用公钥解密签名得到哈希值A
  5. 重新计算固件哈希值B
  6. 比较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 知识体系总览

为了让你更直观地理解这些概念之间的关系,我画了一张图:

密码学基础体系 对称加密 非对称加密 哈希函数 数字签名 私钥签名 + 公钥验签 应用场景:固件签名、安全启动、代码完整性校验 ⚠️ 常见坑:密钥硬编码、使用MD5/SHA-1、签名不验证 对称加密负责效率,非对称加密负责安全,哈希函数负责完整性,三者结合构成数字签名

2.6 实战中的选择建议

我根据多年经验,给你几个实用建议:

  • 固件签名:用ECDSA(椭圆曲线数字签名算法),密钥短、速度快,适合嵌入式
  • 固件加密:用AES-256-GCM,带认证加密,防篡改又防泄露
  • 哈希校验:用SHA-256或SM3,别再用MD5
  • 密钥存储:必须放在HSM或安全元件里,别放Flash

个人经验:我建议你在设计阶段就把密码学方案定下来。等产品量产了再想加签名,那成本可就大了去了。有一次我帮客户做安全审计,发现他们的Bootloader根本没验签——任何固件都能刷进去。嗯,那场面,简直了。

好了,这一章的内容就到这里。密码学基础是固件安全的根基,理解透了,后面的签名实战才能得心应手。