4、数字签名基础:对称加密与非对称加密、哈希函数、RSA与ECDSA算法
各位同学,欢迎来到第四讲。
这一章,我们聊聊数字签名。说白了,数字签名就是给固件打个「指纹」加个「印章」。你想想看,安防设备升级固件时,怎么确保这固件没被人动过手脚?怎么确认它确实是厂家发布的?嗯,数字签名就是干这个的。
4.1 对称加密与非对称加密——先搞清楚这两兄弟
加密这事儿,我习惯把它分成两类:对称加密和非对称加密。
4.1.1 对称加密
对称加密,就是加密和解密用同一把钥匙。就像你家里的大门,用一把钥匙锁上,也用同一把钥匙打开。常见的算法有 AES、DES、SM4。
- 优点:速度快,适合加密大量数据。我在项目中给固件做全量加密时,首选 AES-256。
- 缺点:密钥分发是个大麻烦。你想想,如果我把密钥通过网络传给对方,中途被截获了怎么办?
实际经验:我曾经在一个门禁项目里,直接用对称加密给升级包加密。结果密钥硬编码在代码里,被逆向出来。嗯,从那以后我再也不敢这么干了。
4.1.2 非对称加密
非对称加密,有一对钥匙:公钥和私钥。公钥可以公开,私钥自己藏好。用公钥加密的数据,只有私钥能解开;反过来,用私钥签名的数据,公钥可以验证。
- 常见算法:RSA、ECC(椭圆曲线)、SM2。
- 优点:解决了密钥分发问题。公钥随便发,私钥不泄露就行。
- 缺点:慢。比对称加密慢好几个数量级。所以实际中,我们通常用非对称加密来加密对称密钥,再用对称密钥加密数据。
我的习惯:在安防设备里,我一般用非对称加密做签名验证,用对称加密做数据加密。两者配合,既安全又高效。
4.2 哈希函数——数据的「指纹」
哈希函数,说白了就是把任意长度的数据,压缩成固定长度的摘要。这个摘要就像人的指纹,独一无二。
哈希函数有几个特点:
- 单向性:从摘要反推原始数据,几乎不可能。
- 抗碰撞性:很难找到两个不同的数据,产生相同的哈希值。
- 固定输出:不管输入多大,输出长度固定。比如 SHA-256 输出 256 位。
常见的哈希算法有 MD5(已不推荐)、SHA-1(已不推荐)、SHA-256、SHA-3、SM3。
注意:MD5 和 SHA-1 已经被证明存在碰撞攻击。我在 2018 年审计一个旧项目时,发现还在用 MD5 做固件校验,赶紧让团队换成了 SHA-256。别图省事,安全不能打折。
哈希函数在数字签名中的作用是什么?你想想看,如果直接对几百兆的固件做非对称签名,那得慢死。所以我们先对固件算一个哈希值,然后只对这个哈希值签名。验证时,先算固件的哈希,再用公钥验证签名。这样既快又安全。
4.3 RSA 算法——老牌劲旅
RSA 是 1977 年提出的,到现在还在广泛使用。它的安全性基于大整数分解的困难性。
4.3.1 RSA 的原理
简单说,RSA 用两个大素数 p 和 q 生成密钥。具体步骤:
- 选择两个大素数 p 和 q。
- 计算 n = p × q。
- 计算 φ(n) = (p-1)(q-1)。
- 选择一个 e,通常取 65537。
- 计算 d,使得 e × d ≡ 1 (mod φ(n))。
公钥是 (n, e),私钥是 (n, d)。
4.3.2 RSA 签名与验证
签名过程:用私钥对哈希值进行加密,得到签名。
验证过程:用公钥解密签名,得到哈希值,再与固件的哈希值比对。
避坑指南:我曾经遇到一个项目,RSA 密钥长度只有 1024 位。当时觉得够用了,结果没过两年,NIST 就建议停用 1024 位 RSA。现在我个人习惯至少用 2048 位,关键系统用 4096 位。
4.3.3 RSA 的优缺点
| 优点 | 缺点 |
|---|---|
| 成熟稳定,支持广泛 | 密钥越长,速度越慢 |
| 算法公开,经过多年检验 | 相同安全级别下,密钥比 ECC 长 |
| 实现简单,库支持多 | 对资源受限设备不太友好 |
4.4 ECDSA 算法——后起之秀
ECDSA,全称椭圆曲线数字签名算法。它基于椭圆曲线离散对数问题,安全性更高,密钥更短。
4.4.1 为什么用 ECDSA?
你想想看,RSA 2048 位的密钥,在嵌入式设备上做一次签名验证,可能要几百毫秒。而 ECDSA 用 256 位的密钥,就能达到同样的安全级别,速度还快得多。
我在做智能门锁项目时,MCU 资源非常有限。用 RSA 2048 位验证签名,要 1.2 秒,用户都等得不耐烦了。换成 ECDSA P-256 后,验证时间降到 200 毫秒以内。用户体验好了很多。
4.4.2 ECDSA 的曲线选择
常见的曲线有:
- P-256:NIST 标准曲线,应用最广。
- P-384:更高安全级别。
- P-521:顶级安全。
- Curve25519:性能优化,适合嵌入式。
- SM2:中国国密标准。
我的建议:如果设备资源允许,优先用 P-256 或 SM2。如果追求极致性能,可以考虑 Curve25519。但要注意,有些老旧的安全芯片不支持所有曲线,选型时要提前确认。
4.4.3 ECDSA 的签名过程
ECDSA 签名会生成两个值:r 和 s。验证时,用公钥和签名 (r, s) 来验证哈希值。
// 伪代码示例:ECDSA 签名
// 输入:私钥 d,消息哈希 h
// 输出:签名 (r, s)
1. 生成随机数 k
2. 计算点 (x1, y1) = k * G // G 是基点
3. r = x1 mod n
4. s = k^(-1) * (h + r * d) mod n
5. 返回 (r, s)
重要提醒:ECDSA 的随机数 k 必须每次都不一样,而且必须真随机。我曾经见过一个案例,因为随机数生成器出了问题,导致两次签名用了相同的 k,结果私钥被直接算出来了。嗯,这可不是闹着玩的。
4.5 RSA vs ECDSA——怎么选?
| 对比项 | RSA | ECDSA |
|---|---|---|
| 安全级别 | 2048 位 ≈ 112 位安全 | 256 位 ≈ 128 位安全 |
| 密钥长度 | 2048 位 | 256 位 |
| 签名速度 | 较慢 | 较快 |
| 验证速度 | 较快 | 较快 |
| 资源消耗 | 高 | 低 |
| 成熟度 | 极高 | 高 |
| 适用场景 | PC、服务器 | 嵌入式、IoT 设备 |
我个人习惯:如果是资源充足的网关或服务器,用 RSA 2048 位以上。如果是资源受限的传感器、门锁、摄像头,用 ECDSA P-256 或 SM2。没有绝对的好坏,只有合不合适的场景。
4.6 数字签名在安防系统中的应用
好了,理论讲完了,我们看看实际怎么用。
4.6.1 固件签名流程
- 开发阶段:厂家用私钥对固件哈希进行签名,生成签名文件。
- 发布阶段:固件和签名文件一起发布。
- 升级阶段:设备收到固件后,先算哈希,再用公钥验证签名。
- 验证通过:才允许升级。否则拒绝。
4.6.2 公钥的存储
公钥必须安全地存储在设备里。我一般把它放在安全芯片或 eFuse 中,防止被篡改。如果公钥被换了,那签名验证就形同虚设。
经验之谈:我曾经审计过一个摄像头项目,公钥竟然放在文件系统里,而且没做任何保护。攻击者只要替换公钥,就能用自己的固件升级。这种漏洞,说白了就是给黑客留后门。
4.6.3 安全启动链
在安防系统中,数字签名是安全启动链的一环。从 BootROM 开始,逐级验证:
- BootROM 验证 Bootloader 的签名
- Bootloader 验证内核的签名
- 内核验证文件系统的签名
- 应用层验证升级包的签名
每一级都信任上一级的公钥,形成一条信任链。只要根信任是安全的,整个系统就是安全的。
4.7 本章小结
这一章我们聊了:
- 对称加密和非对称加密的区别
- 哈希函数的作用和注意事项
- RSA 和 ECDSA 的原理与对比
- 数字签名在安防系统中的应用
下一章,我们会深入实战,讲讲如何在嵌入式设备上实现安全启动。到时候我会带大家一步步写代码,把今天学的知识用起来。
课后思考:如果你的设备只有 64KB 的 Flash 和 8KB 的 RAM,你会选择 RSA 还是 ECDSA?为什么?