3. 加密基础:对称加密(AES)、非对称加密(RSA)、哈希函数(SHA-256)的应用场景

聊到安全更新,加密是绕不开的基石。很多人觉得加密就是「把数据变乱码」,其实没那么玄乎。我做了这么多年安全,说白了,加密就干三件事:藏起来、验身份、防篡改。今天咱们就把这三板斧——AES、RSA、SHA-256 掰开揉碎了讲清楚。

3.1 对称加密:AES 的「一把钥匙开一把锁」

对称加密,顾名思义,加密和解密用同一把钥匙。就像你家大门,用钥匙锁上,再用同一把钥匙打开。AES(Advanced Encryption Standard)是目前最主流的对称加密算法,没有之一。

核心要点:AES 的密钥长度可以是 128、192 或 256 位。我个人习惯用 AES-256,虽然慢一丢丢,但安全冗余更足。在安全更新场景里,固件包本身往往先用 AES 加密,因为对称加密速度快,适合处理大文件。

我在项目中遇到过一个问题:某 IoT 设备升级固件,直接用 AES 加密整个包,密钥硬编码在代码里。结果固件被提取后,密钥直接暴露。嗯,这里要注意——AES 的短板就是密钥分发。你想想看,如果通信双方事先没有约定好密钥,怎么安全地传递它?这就引出了非对称加密。

AES 的典型应用场景

  • 固件/镜像加密:更新包体积大,AES 加解密速度快,适合批量处理。
  • 本地数据存储:比如数据库字段加密、配置文件加密。
  • VPN 隧道加密:IPsec 和 WireGuard 底层都用 AES。

避坑指南:我曾经见过有人用 ECB 模式加密固件,结果相同的数据块产生了相同的密文,攻击者直接通过模式识别还原了部分内容。记住,生产环境永远用 AES-GCM 或 AES-CBC + HMAC,别碰 ECB。

3.2 非对称加密:RSA 的「公钥锁、私钥开」

非对称加密解决了密钥分发难题。它有一对钥匙:公钥公开,私钥自己藏好。公钥加密的数据只有私钥能解,反过来,私钥签名的东西公钥能验。RSA 是最经典的非对称算法,虽然现在 ECC(椭圆曲线)逐渐流行,但 RSA 在安全更新领域依然根深蒂固。

说白了,RSA 在安全更新里主要干两件事:加密对称密钥和数字签名。你想想看,固件那么大,用 RSA 直接加密不现实(RSA 最多加密密钥长度那么大的数据,比如 2048 位只能加密 256 字节)。所以实际做法是:用 RSA 加密 AES 密钥,再用 AES 加密固件本体。这叫「混合加密」。

RSA 的典型应用场景

  • 密钥交换:客户端用服务器公钥加密一个随机生成的 AES 密钥,服务器用私钥解密。
  • 数字签名:对固件哈希值做 RSA 签名,设备端用公钥验签,确保固件来源可信。
  • 证书验证:HTTPS 和代码签名证书底层都是 RSA(或 ECC)。

注意:RSA 的密钥长度低于 2048 位已经不安全了。我记得 2017 年有个项目用了 1024 位 RSA,结果被学术界证明可以在普通服务器上几天内破解。现在最低标准是 2048 位,我建议直接上 4096 位,尤其是签名场景。

3.3 哈希函数:SHA-256 的「数字指纹」

哈希函数不是加密,它没有密钥,也不可逆。它的作用是把任意长度的数据,映射成一个固定长度的摘要(比如 SHA-256 输出 256 位)。这个摘要就像数据的「指纹」——哪怕原文件只改了一个比特,哈希值都会天翻地覆。

在安全更新里,哈希函数无处不在。你下载固件时,服务器会同时提供一个 SHA-256 值。设备下载完后自己算一遍,比对一下,就知道固件有没有被篡改。这就是完整性校验。

SHA-256 的典型应用场景

  • 固件完整性校验:下载后计算哈希,与官方公布的值比对。
  • 密码存储:存储密码的哈希值(注意要加盐,别直接用 SHA-256 裸存)。
  • 数字签名的基础:先对固件做 SHA-256,再对哈希值做 RSA 签名,效率更高。
  • 数据去重:用哈希值作为唯一标识,判断文件是否已存在。

一个常见的误解:很多人以为 SHA-256 是「加密」,其实它不是。哈希是单向的,你无法从哈希值还原原文。我曾经在代码评审里看到有人把密码用 SHA-256 哈希后存数据库,以为这样就安全了。但没加盐的哈希,彩虹表一查就破。记住,存储密码要用 bcrypt 或 Argon2,SHA-256 只适合做完整性校验。

3.4 三种技术的协同:安全更新的完整链路

实际的安全更新流程,从来不是只用一种技术。我画了一张图,帮你理清它们怎么配合的。

安全更新加密链路图 安全更新加密链路图 固件源文件 SHA-256 哈希值 (摘要) RSA 签名 数字签名 AES 加密 加密固件包 安全更新包 (加密固件 + 签名) 流程说明: 1. 对固件源文件计算 SHA-256 哈希值,确保完整性。 2. 用 RSA 私钥对哈希值签名,确保来源可信。 3. 用随机生成的 AES 密钥加密固件本体,确保机密性。 4. 将加密固件 + 数字签名打包,分发给设备。 5. 设备端:RSA 公钥验签 → SHA-256 比对 → AES 解密。

3.5 三种技术的对比与选型

我整理了一张表,方便你快速对比。选型时记住一句话:速度用 AES,安全分发用 RSA,完整性校验用 SHA-256。

特性 AES (对称) RSA (非对称) SHA-256 (哈希)
密钥数量 1 个(共享密钥) 2 个(公钥 + 私钥) 无密钥
加解密速度 极快(硬件加速常见) 慢(尤其私钥操作) 快(但不可逆)
主要用途 数据加密 密钥交换 / 数字签名 完整性校验 / 指纹
典型密钥长度 128 / 192 / 256 位 2048 / 4096 位 256 位(输出)
安全更新角色 加密固件内容 签名验证 + 加密 AES 密钥 校验固件是否被篡改
抗量子计算 弱(Grover 算法减半强度) 弱(Shor 算法可破解) 较强(仅需加倍输出长度)

我的个人习惯:在安全更新系统里,我通常这样组合:

  • 固件加密:AES-256-GCM(自带认证,防篡改)
  • 密钥封装:RSA-4096 OAEP(安全填充)
  • 签名算法:RSA-4096 PKCS#1 v1.5 或 PSS(对哈希值签名)
  • 完整性校验:SHA-256(配合签名一起用)

这个组合在性能和安全性之间取得了不错的平衡。当然,如果设备算力允许,也可以考虑 ECC(比如 ECDSA + ECDH),密钥更短,速度更快。

3.6 实战中的常见误区

最后,我分享几个我在项目中踩过的坑,希望能帮你少走弯路。

  1. 直接用 RSA 加密大文件:RSA 有长度限制,2048 位密钥最多加密 256 字节。正确做法是「混合加密」——用 RSA 加密 AES 密钥,用 AES 加密数据。
  2. 哈希值不签名:只提供 SHA-256 值,但不签名。攻击者可以同时替换固件和哈希值,设备无法察觉。记住,哈希值必须通过可信渠道传递,或者用私钥签名。
  3. 密钥硬编码:把 AES 密钥或 RSA 私钥直接写在代码里。我曾经在某个路由器固件里看到硬编码的私钥,攻击者提取后可以伪造任何更新。密钥应该存储在安全硬件(如 TPM、Secure Element)中。
  4. 忽略随机数质量:AES 的 IV(初始化向量)和 RSA 的随机填充都需要高质量的随机数。用 /dev/urandom 或硬件随机数生成器,别用 rand()。