4、数字签名原理:非对称加密基础、签名与验签流程、RSA与ECDSA算法

数字签名,说白了就是给固件打上一个「防伪标签」。你想想看,OTA 升级时设备从云端下载了一个固件包,怎么确认这个包确实是官方发布的、没有被篡改过?靠的就是数字签名。

我刚开始做嵌入式安全时,总觉得签名就是个「加密的反向操作」,后来踩了坑才明白——签名不是加密,它解决的是完整性和身份认证问题,不是保密问题。

4.1 非对称加密基础

数字签名的根基是非对称加密。它有一对密钥:私钥(自己藏好)和公钥(公开出去)。

  • 私钥签名,公钥验签——这是签名体系的核心原则。
  • 私钥一旦泄露,整个信任链就崩了。
  • 公钥可以随便分发,但必须保证它的真实性(后面讲证书链时会细说)。

我在项目中遇到过一件事:某次产线烧录时,公钥被写错了几个字节,结果所有设备升级都验签失败。排查了两天才发现是烧录脚本的问题。嗯,从那以后我养成了一个习惯——验签前先校验公钥的哈希值。

核心概念:非对称加密中,加密和解密使用不同密钥;签名和验签也使用不同密钥。私钥只能由签名方持有,公钥可以公开。

4.2 签名与验签流程

签名流程其实不复杂,我画了一张图帮你理解:

数字签名与验签流程 签名方(服务器) 固件 → 哈希算法 → 摘要 摘要 + 私钥 → 签名值 输出:固件 + 签名值 传输 验签方(设备) 固件 → 哈希算法 → 摘要1 签名值 + 公钥 → 摘要2 比较摘要1 == 摘要2? 匹配 → 签名有效 | 不匹配 → 签名无效 注意:哈希算法必须一致,否则验签必然失败 公钥必须提前安全地预置在设备中

流程拆开来看,其实就三步:

  1. 计算摘要:对固件做哈希运算(比如 SHA-256),得到固定长度的摘要。
  2. 私钥签名:用私钥对摘要进行签名运算,生成签名值。
  3. 打包分发:把固件和签名值一起发给设备。

设备收到后,验签流程也是三步:

  1. 计算摘要:对收到的固件做同样的哈希运算,得到摘要1。
  2. 公钥解密:用公钥对签名值进行验签运算,得到摘要2。
  3. 比较摘要:如果摘要1 == 摘要2,说明固件是完整的、来源可信。

我的经验:验签时一定要做「恒定时间比较」,不能用 memcmp 直接比。否则攻击者可以通过时序攻击猜出摘要内容。我曾经在某个 IoT 项目里发现过这个漏洞,修复后性能损失不到 1%,但安全性提升了一个量级。

4.3 RSA 算法

RSA 是目前最广泛使用的签名算法之一。它的安全性基于大整数分解的困难性。

参数 说明 典型值
密钥长度 模数 n 的位数 2048 / 4096 位
签名长度 等于密钥长度 256 / 512 字节
计算速度 验签快,签名慢 签名约 1ms,验签约 0.1ms(2048位)
安全性 依赖大数分解 2048位目前安全

RSA 的签名过程,说白了就是「用私钥做模幂运算」。验签时用公钥做同样的运算,然后比对结果。

// RSA 签名伪代码(简化版)
// 签名
digest = SHA256(firmware)
signature = RSA_sign(private_key, digest)

// 验签
digest1 = SHA256(firmware)
digest2 = RSA_verify(public_key, signature)
if (digest1 == digest2) {
    // 签名有效
}

避坑指南:RSA 签名一定要使用 PSS 填充模式,不要用 PKCS#1 v1.5。我曾经在审计一个老项目时发现,v1.5 填充存在 Bleichenbacher 攻击风险,攻击者可以伪造签名。PSS 模式虽然计算量稍大,但安全性高得多。

4.4 ECDSA 算法

ECDSA(椭圆曲线数字签名算法)是 RSA 的现代替代方案。它的优势在于:更短的密钥、更快的计算、同等的安全性。

对比项 RSA-2048 ECDSA-P256
密钥长度 2048 位 256 位
签名长度 256 字节 64 字节
安全性等级 112 位 128 位
签名速度 较慢 快 3-5 倍
验签速度 较快 快 2-3 倍

ECDSA 的安全性基于椭圆曲线离散对数问题。说白了,就是给定椭圆曲线上的点 P 和 kP,很难反推出 k 的值。

我在项目中更倾向于使用 ECDSA,尤其是在资源受限的嵌入式设备上。原因很简单:签名短、省带宽、省存储。OTA 升级包动辄几十 MB,签名值每少 192 字节,对千万级设备来说就是几十 GB 的流量节省。

选型建议:

  • 如果设备有硬件加速模块(如 ARM CryptoCell),优先用 ECDSA。
  • 如果兼容性要求高(比如需要和旧系统对接),选 RSA。
  • 如果对签名长度敏感(比如 LoRa、NB-IoT 等窄带通信),必须用 ECDSA。

4.5 算法对比与选型

我整理了一张对比表,方便你快速决策:

维度 RSA ECDSA
密钥生成 慢(需要找大素数) 快(随机数 + 基点运算)
签名长度 256-512 字节 64-72 字节
计算资源 CPU 占用高 CPU 占用低
硬件支持 广泛 逐渐普及
专利问题 已过期 部分曲线有专利
推荐场景 PC/服务器端 嵌入式/IoT 设备

我的建议:新项目直接上 ECDSA P-256 曲线。它被 NIST 推荐,专利已过期,硬件支持也越来越好。如果实在担心兼容性,可以同时支持 RSA 和 ECDSA,但默认用 ECDSA。

最后说一句:算法本身不是安全的全部。密钥管理、随机数生成、侧信道防护,这些环节任何一个出问题,再强的算法也白搭。我见过太多「算法选对了,实现搞砸了」的案例了。