密码学基础(上):对称加密、非对称加密与哈希函数
说实话,很多做OTA的工程师一开始都觉得密码学是数学家的事。我当年也这么想——直到第一次看到固件被逆向破解,签名被伪造,更新包被篡改。嗯,从那以后我老老实实把这几块基础啃完了。
这一章我们只聊三样东西:AES、RSA/ECC、SHA-256。它们在OTA里各司其职,缺一不可。你想想看,更新包从云端到设备,要保密、要防篡改、要验证来源——正好对应这三类算法。
1. 对称加密:AES
对称加密,说白了就是一把钥匙开一把锁。加密和解密用同一个密钥。在OTA场景里,我们通常用AES来加密固件本身。
我个人习惯用AES-256-GCM。为什么?因为GCM模式自带认证标签,能同时检测数据是否被篡改。我在一个车机项目里遇到过,有人用AES-ECB模式加密固件,结果每个16字节块独立加密,攻击者可以重排块顺序——设备照样解密成功,但跑的是被调换过的代码。嗯,从那以后我再也不用ECB了。
AES在OTA中的典型用法:
- 加密固件负载:云端用AES密钥加密固件,设备用相同密钥解密。
- 加密传输通道:如果TLS不可用,AES可以用来保护更新包的传输。
- 加密存储:设备收到固件后,用AES加密存储在Flash中,防止物理读取。
// AES-256-GCM 加密示例(伪代码)
key = random_bytes(32) // 256位密钥
iv = random_bytes(12) // 96位随机IV
ciphertext, tag = aes_gcm_encrypt(key, iv, firmware_data)
// 传输时:iv + ciphertext + tag
2. 非对称加密:RSA 与 ECC
非对称加密,公钥加密,私钥解密。在OTA里,我们主要用它来做两件事:数字签名和密钥交换。
你想想看,如果云端用私钥签名固件,设备用公钥验签——只要公钥没被篡改,设备就能确认固件来自真正的云端。这就是OTA安全的基石。
RSA vs ECC:怎么选?
| 对比项 | RSA (2048位) | ECC (256位) |
|---|---|---|
| 安全等级 | 112位 | 128位 |
| 密钥长度 | 2048位 | 256位 |
| 签名速度 | 慢 | 快 |
| 验签速度 | 快 | 较快 |
| 资源消耗 | 高(尤其私钥操作) | 低 |
| OTA推荐场景 | 云端签名(计算资源充足) | 设备端验签(资源受限) |
我在一个IoT项目里踩过坑:用RSA-2048在Cortex-M4上做签名验证,每次验签要花将近2秒。后来换成ECC-256,降到200毫秒以内。设备端验签是高频操作,ECC明显更友好。
OTA中的典型签名流程:
- 云端计算固件的SHA-256哈希值。
- 用私钥对哈希值签名,生成签名数据。
- 设备收到固件 + 签名后,用公钥验签。
- 验签通过,才允许安装固件。
// ECDSA 签名与验签(伪代码)
// 云端签名
hash = sha256(firmware_data)
signature = ecdsa_sign(private_key, hash)
// 设备验签
hash = sha256(firmware_data)
valid = ecdsa_verify(public_key, hash, signature)
if (!valid) reject_update()
3. 哈希函数:SHA-256
哈希函数,输入任意长度数据,输出固定长度摘要。SHA-256输出256位,也就是32字节。它的核心特性是单向性和抗碰撞性——你没法从哈希值反推原文,也很难找到两个不同输入产生相同哈希。
在OTA里,哈希函数无处不在:
- 完整性校验:设备下载完固件后,计算SHA-256,与云端公布的哈希值对比。不一致就说明数据被篡改。
- 签名的基础:非对称签名不是直接签固件,而是签固件的哈希。因为固件可能很大,哈希后只有32字节,签名效率高得多。
- 增量更新:差分OTA中,用哈希来识别哪些块发生了变化。
我个人习惯在OTA更新包中同时包含两个哈希值:一个是固件整体的SHA-256,另一个是每个分块的哈希列表。这样设备可以边下载边校验,不用等全部下载完才发现数据坏了。
// 分块哈希校验示例
block_size = 4096
for each block in firmware:
block_hash = sha256(block)
block_hashes.append(block_hash)
// 传输时:block_hashes + firmware + overall_hash + signature
4. 三者在OTA中的协同工作
光讲理论没意思,我们直接看一个真实的OTA安全更新流程:
- 云端准备:用AES-256-GCM加密固件,生成密文和认证标签。
- 云端签名:计算密文的SHA-256哈希,用ECC私钥签名。
- 打包传输:将AES密钥(用设备公钥加密)、IV、密文、签名打包成更新包。
- 设备接收:用设备私钥解密AES密钥,得到对称密钥。
- 设备验签:计算密文哈希,用云端公钥验签。
- 设备解密:验签通过后,用AES密钥解密固件。
- 设备校验:解密后的固件再算一次哈希,与云端公布的固件哈希对比。
- 安装:全部通过,才允许刷写固件。
你看,AES负责保密,RSA/ECC负责身份认证和密钥分发,SHA-256负责完整性。三者环环相扣,少一个都不行。