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

各位同学,欢迎来到《安全启动与固件签名实战课》的第二章。

说实话,密码学是安全启动的基石。没有它,后面讲的签名、验签、信任链全是空中楼阁。我当年刚接触嵌入式安全时,总觉得密码学是数学家的事,跟我一个写C的工程师没关系。直到有一次,我在一个IoT项目里因为选错了加密算法,导致固件被逆向得一干二净……嗯,从那以后,我老老实实把基础补上了。

今天我们就来啃这三块硬骨头:对称加密与非对称加密、哈希函数、数字签名。别怕,我会用实战的视角带你过一遍。


2.1 对称加密:一把钥匙开一把锁

对称加密,说白了就是加密和解密用同一把密钥。你想想看,就像你家大门,用一把钥匙锁上,也用同一把钥匙打开。

2.1.1 工作原理

发送方用密钥K对明文加密,得到密文。接收方收到密文后,用同一个密钥K解密,还原出明文。

核心公式:

  • 加密:C = E(K, P)
  • 解密:P = D(K, C)

其中P是明文,C是密文,K是密钥,E和D分别是加解密算法。

2.1.2 常见算法

算法 密钥长度 特点 我的建议
AES 128/192/256位 速度快,硬件支持好 嵌入式首选,没有之一
DES 56位 已淘汰,可被暴力破解 千万别用,除非你想被骂
3DES 112/168位 兼容旧系统,但慢 能不用就不用
SM4 128位 国密标准,国内项目必备 做国内项目必须支持

实战小贴士:我在做MCU固件加密时,90%的场景都用AES-128-CTR模式。为什么?因为CTR模式可以并行计算,而且不需要填充,对Flash存储特别友好。但记住,CTR模式绝对不能重复使用相同的IV,否则加密就形同虚设。

2.1.3 对称加密的痛点

你可能会问:既然对称加密又快又简单,为什么还要学别的?

问题出在密钥分发上。如果A要给B发密文,A得先把密钥安全地交给B。但怎么交?如果通过网络传,密钥本身就可能被截获。这就是所谓的密钥配送问题。

我曾经在一个项目里,为了给1000台设备预置密钥,不得不专门派人去工厂烧录。那叫一个折腾。


2.2 非对称加密:公钥私钥,各司其职

非对称加密解决了密钥配送问题。它使用一对密钥:公钥(Public Key)和私钥(Private Key)。公钥可以公开,私钥必须保密。

2.2.1 核心思想

  • 公钥加密,私钥解密:任何人都可以用你的公钥加密消息,但只有你能用私钥解密。
  • 私钥签名,公钥验签:你可以用私钥签名一段数据,别人用你的公钥验证签名是否是你本人所为。

记住这个口诀:

公钥加密私钥解,私钥签名公钥验。

前者保证机密性,后者保证认证性。

2.2.2 常见算法

算法 密钥长度 安全强度 嵌入式适用性
RSA 2048/4096位 高 慢,占用资源多
ECC 256/384位 高(同等安全下密钥更短) 非常适合嵌入式
SM2 256位 高(国密) 国内项目首选
Ed25519 256位 极高 性能好,推荐新项目使用

⚠️ 重要警告:千万不要在嵌入式设备上用RSA-1024!它已经被证明不安全。我见过一些老项目还在用RSA-1024签名,结果被侧信道攻击打得体无完肤。至少用RSA-2048,或者直接上ECC。

2.2.3 混合加密:取长补短

非对称加密虽然解决了密钥分发问题,但速度慢得令人发指。RSA-2048加密1KB数据,在普通MCU上可能要几百毫秒。

所以实际项目中,我们通常用混合加密:

  1. 用非对称加密传输一个临时对称密钥(会话密钥)。
  2. 用这个对称密钥加密后续的所有数据。

这就是HTTPS的底层逻辑。TLS握手时用非对称加密交换密钥,之后用AES加密传输数据。


2.3 哈希函数:数据的指纹

哈希函数,也叫散列函数。它能把任意长度的数据,压缩成固定长度的摘要(Digest)。

2.3.1 三大特性

  • 单向性:从摘要无法反推出原始数据。说白了,就是不可逆。
  • 抗碰撞性:很难找到两个不同的输入,产生相同的输出。
  • 雪崩效应:输入哪怕只改一个比特,输出也会面目全非。

哈希函数不是加密!

加密是为了隐藏数据,可以解密。哈希是为了验证完整性,不能解密。很多新手把这两个搞混,结果在固件校验时出了大问题。

2.3.2 常见算法

算法 输出长度 状态 我的推荐
MD5 128位 已破解,不安全 绝对不要用
SHA-1 160位 已破解,不推荐 能不用就不用
SHA-256 256位 安全 嵌入式首选
SHA-3 224/256/384/512位 安全,新一代标准 新项目可以考虑
SM3 256位 安全(国密) 国内项目必备

实战经验:我在做固件完整性校验时,通常先计算整个固件的SHA-256哈希值,然后把这个哈希值存到固件头的保留字段里。启动时,Bootloader重新计算哈希,跟存储的值比对。如果对不上,说明固件被篡改了。

但注意,光有哈希还不够——攻击者可以同时篡改固件和哈希值。这时候就需要数字签名了。


2.4 数字签名:防伪与防抵赖

数字签名结合了哈希函数和非对称加密。它解决了三个问题:

  • 完整性:数据有没有被改过?
  • 认证性:数据是谁发的?
  • 不可抵赖性:发信人能否否认发过这个数据?

2.4.1 签名与验签流程

我画了一张图,帮你理清整个流程:

数字签名与验签流程 数字签名与验签流程 签名方(私钥签名) 原始数据 哈希函数(SHA-256) 摘要(哈希值) 私钥签名 签名值 验签方(公钥验签) 接收数据 + 签名值 哈希函数(SHA-256) 摘要1(计算值) 公钥验签 → 摘要2 比对:摘要1 == 摘要2? 传输:数据 + 签名值 核心逻辑:先哈希后签名,验签时重新计算哈希并比对

2.4.2 签名过程(发送方)

  1. 对原始数据计算哈希值(摘要)。
  2. 用私钥对摘要进行加密,得到签名值。
  3. 将原始数据和签名值一起发送给接收方。

2.4.3 验签过程(接收方)

  1. 用同样的哈希函数计算接收到的数据的哈希值(摘要1)。
  2. 用公钥解密签名值,得到摘要2。
  3. 比对摘要1和摘要2。如果一致,说明数据完整且来自合法的签名方。

⚠️ 避坑指南:我曾经在一个项目中,看到有人直接用私钥加密整个固件,然后公钥解密来验证。这是错的!非对称加密非常慢,加密整个固件会慢到让你怀疑人生。正确的做法是先哈希,再签名哈希值。这样无论固件多大,签名都只需要处理一个固定长度的摘要。

2.4.4 常见签名算法

算法 底层 签名长度 嵌入式推荐度
RSA-PSS RSA 256/512字节 ⭐⭐⭐
ECDSA ECC 64/96字节 ⭐⭐⭐⭐⭐
EdDSA (Ed25519) ECC 64字节 ⭐⭐⭐⭐⭐
SM2 ECC 64字节 ⭐⭐⭐⭐(国密)

我的选择:新项目我无脑推荐Ed25519。签名只有64字节,验签速度比ECDSA快好几倍,而且实现简单,不容易出错。如果你做国内项目,那就用SM2,性能也相当不错。


2.5 本章小结

好了,我们来捋一捋今天的内容:

  • 对称加密:快,但密钥分发麻烦。适合加密大量数据。
  • 非对称加密:慢,但解决了密钥分发问题。适合加密小数据或交换密钥。
  • 哈希函数:不可逆,用于验证完整性。但容易被篡改。
  • 数字签名:哈希 + 非对称加密,同时保证完整性、认证性和不可抵赖性。