4、数字签名基础:非对称加密原理
聊到固件完整性校验,数字签名是绕不开的核心技术。说白了,它就是给固件贴上一张「防伪标签」,谁要是敢篡改,一验就知道。
我记得刚入行那会儿,总觉得数字签名是个黑盒子——公钥、私钥、签名、验签,听着就头大。后来亲手调过几回签名验证的代码,踩过坑,才真正理解这东西到底怎么工作的。
4.1 非对称加密:公钥与私钥
传统对称加密,好比一把钥匙开一把锁。加密和解密用同一个密钥,问题来了——你怎么安全地把这把钥匙交给对方?
非对称加密就不一样了。它用一对密钥:公钥和私钥。
- 私钥:自己死死藏好,谁都不给。签名用的就是它。
- 公钥:公开出去,谁要都行。验签用的就是它。
你想想看,私钥签名,公钥验签。私钥只有你自己有,所以签名只有你能生成。别人拿到公钥,只能验证签名是不是你签的,但伪造不了。
核心原则:私钥签名,公钥验签。私钥永远不离开你的安全环境。
我在项目里见过有人把私钥硬编码在固件里,结果固件被反编译,私钥直接暴露。嗯,这属于「教科书级」的失误,千万别学。
4.2 数字签名流程:签名与验签
数字签名到底怎么做的?我拆成两步讲清楚。
4.2.1 签名过程(发送方)
- 对固件数据计算哈希值(比如 SHA-256)。
- 用私钥对哈希值加密,生成签名。
- 把固件 + 签名一起发出去。
你看,签名不是对整个固件加密,那太慢了。实际是对固件的「指纹」(哈希值)加密。这样既保证效率,又保证唯一性。
4.2.2 验签过程(接收方)
- 收到固件和签名后,先对固件算一遍哈希值。
- 用公钥解密签名,得到原始的哈希值。
- 对比两个哈希值。一致 → 固件完整且来源可信;不一致 → 固件被篡改或签名无效。
我的习惯:验签失败时,不要只弹个警告就继续运行。直接拒绝加载,或者进入安全恢复模式。我曾经见过一个设备,验签失败后只是记了条日志,结果被攻击者利用这个漏洞刷入了恶意固件。
为什么会这样?因为签名验证是固件安全的最后一道防线。一旦跳过或忽略,前面做的所有防护都白费了。
4.3 RSA 与 ECDSA 算法简介
目前主流签名算法就两种:RSA 和 ECDSA。我分别说说它们的脾气。
| 特性 | RSA | ECDSA |
|---|---|---|
| 安全性基础 | 大整数分解 | 椭圆曲线离散对数 |
| 密钥长度 | 2048 / 4096 位 | 256 / 384 位 |
| 签名速度 | 较慢 | 较快 |
| 验签速度 | 较快 | 较慢 |
| 签名体积 | 较大(256 字节 @2048位) | 较小(64 字节 @256位) |
| 典型场景 | PC、服务器、网关 | IoT 设备、嵌入式系统 |
4.3.1 RSA
RSA 是「老大哥」,1997 年就标准化了。算法成熟,硬件支持广泛。很多安全芯片都内置了 RSA 加速引擎。
但它的缺点也很明显:密钥太长。2048 位的 RSA 密钥,签名有 256 字节。对于资源受限的 IoT 设备,传输和存储都是负担。
我建议:如果你的设备有专用安全芯片,或者对性能要求不高,RSA 是稳妥的选择。毕竟它经过了二十多年的攻击考验。
4.3.2 ECDSA
ECDSA 是「后起之秀」。同样的安全强度,密钥长度只有 RSA 的十分之一。256 位的 ECDSA 密钥,安全等级相当于 3072 位的 RSA。
这对嵌入式设备太友好了。签名体积小,传输快,存储省。我最近做的几个 IoT 项目,全部换成了 ECDSA。
注意:ECDSA 依赖随机数质量。如果随机数生成器有缺陷,私钥可能被恢复。我曾经调试过一个设备,因为硬件随机数发生器坏了,ECDSA 签名总是失败。后来加了软件熵池才解决。
选哪个?我个人倾向:新项目优先 ECDSA,尤其是资源受限的嵌入式环境。如果项目有历史包袱,或者需要兼容已有 PKI 体系,RSA 也没问题。
4.4 数字签名流程总览
下面这张图,把签名和验签的完整流程串起来了。我建议你多看几遍,直到能在脑子里「跑通」整个流程。
这张图把签名和验签的完整路径画清楚了。左边是签名方,右边是验签方。中间那条虚线代表传输过程。你仔细看,两个哈希值在最后一步比较,这就是整个安全机制的「命门」。
避坑指南:我曾经在项目里犯过一个低级错误——验签时忘了比较哈希值,只检查了签名能不能用公钥解开。结果攻击者随便改个数据,签名照样能解开(虽然解出来是乱码),但我的代码没做哈希比对,直接通过了。嗯,从那以后我写验签代码,第一件事就是确认哈希比较逻辑有没有写对。