3、密码学基础(下):数字签名(RSA-PSS/ECDSA)、证书链、公钥基础设施(PKI)在设备身份认证中的应用

上一讲我们聊了哈希和对称/非对称加密。说白了,那些是「锁门」和「验证指纹」的工具。但IoT设备真正要解决的,是「我怎么知道你是谁?」以及「你给我的固件有没有被人动过手脚?」。

这两个问题,靠的就是数字签名、证书链和PKI。我做了这么多年嵌入式安全,见过太多设备因为签名校验没做好,被黑客直接刷了恶意固件。嗯,咱们今天就把这块彻底讲透。

3.1 数字签名:不只是「加密的反向」

很多人以为数字签名就是「用私钥加密,用公钥解密」。其实不对。你想想看,非对称加密慢得要命,拿它去加密整个固件?那设备得卡死。

真正的做法是:先对固件算一个哈希值(比如SHA-256),然后只对这个哈希值做签名。验证的时候,同样先算哈希,再用公钥验签。这样既快又安全。

3.1.1 RSA-PSS:带盐的概率签名

RSA-PSS(Probabilistic Signature Scheme)是RSA签名的一种改进模式。它引入了随机盐值(salt),每次签名结果都不一样。这能防止某些选择明文攻击。

我在一个智能门锁项目里就吃过亏。当时用了老旧的PKCS#1 v1.5签名,结果被攻击者利用填充预言机攻击,硬是把签名给伪造了。后来全部换成RSA-PSS,问题才解决。

避坑指南: 我曾经在IoT设备上直接用了OpenSSL默认的RSA签名(PKCS#1 v1.5)。虽然也能用,但安全性差了一个量级。现在新设计我全部强制使用RSA-PSS,盐值长度至少32字节。

RSA-PSS的签名流程大致如下:

  1. 对原始消息M计算哈希值H = Hash(M)
  2. 生成随机盐值Salt(通常16~64字节)
  3. 将H和Salt拼接,再次哈希,得到中间值H'
  4. 构造填充块,包含H'、Salt、以及一些固定填充字节
  5. 用私钥对填充块做模幂运算,得到签名S

验证时,接收方用公钥解密签名,取出Salt,重新计算一遍,比对结果是否一致。

3.1.2 ECDSA:椭圆曲线签名,IoT的宠儿

ECDSA(Elliptic Curve Digital Signature Algorithm)是目前IoT设备上最主流的签名算法。为什么?因为同样的安全强度下,它的密钥长度只有RSA的1/10左右。

安全等级RSA密钥长度ECDSA密钥长度
80位1024位160位
112位2048位224位
128位3072位256位
256位15360位512位

你看,128位安全等级下,RSA要3072位,ECDSA只要256位。对于Flash和RAM都捉襟见肘的IoT设备,这差距就是能不能跑起来的区别。

ECDSA的核心依赖椭圆曲线上的离散对数难题。签名过程涉及随机数k的生成——这里有个大坑。我见过一个案例,某厂商的随机数生成器有bug,导致每次签名用的k值都一样。攻击者直接通过两次签名就反推出了私钥。整个产品线的设备全部沦陷。

个人经验: 我习惯在ECDSA签名前,强制检查随机数质量。如果硬件TRNG(真随机数发生器)不可靠,就退回到确定性ECDSA(RFC 6979),用私钥+消息哈希来派生k值,彻底避免随机数问题。

3.2 证书链:信任的传递

光有签名还不够。你拿着公钥去验签,但公钥本身怎么保证是真的?如果攻击者替换了设备里的公钥,那签名验得再严也没用。

这就是证书链要解决的问题。说白了,就是「你妈是你妈」的证明——通过一层层上级机构的背书,把信任从根传递到叶子。

3.2.1 X.509证书结构

一个典型的X.509证书包含:

  • 版本号:目前主流是v3
  • 序列号:CA签发的唯一编号
  • 签名算法:比如sha256WithRSAEncryption
  • 颁发者:签发该证书的CA名称
  • 有效期:起止时间
  • 主体:证书持有者名称
  • 公钥:持有者的公钥信息
  • 扩展:密钥用途、基本约束等
  • 签名:CA对上述内容的数字签名

在IoT设备里,我们通常只存一个根证书(或者中间CA证书),然后验证固件签名时,把固件附带的设备证书和签名一起校验。

3.2.2 证书链验证流程

假设设备A要验证固件B的签名:

  1. 设备A内置了根CA证书(自签名,信任锚点)
  2. 固件B附带了一个设备证书C,以及一个中间CA证书D
  3. 设备A先用根CA证书的公钥,验证中间CA证书D的签名
  4. 如果D有效,再用D的公钥验证设备证书C的签名
  5. 如果C有效,最后用C的公钥验证固件B的签名

这个过程就是证书链验证。每一级都用自己的上级公钥来验签,直到信任的根。

核心要点: 证书链的本质是「信任传递」。根CA是信任锚点,中间CA是代理,叶子证书是最终实体。只要根证书没被攻破,整条链就是安全的。

3.3 公钥基础设施(PKI)在设备身份认证中的应用

PKI不是某个算法,而是一整套体系。它包括CA(证书颁发机构)、RA(注册机构)、证书库、CRL(证书吊销列表)等组件。

在IoT场景下,PKI主要解决三个问题:

  • 设备身份认证:证明「我是合法的设备」
  • 安全通信:TLS握手时交换证书,建立加密通道
  • 固件签名验证:确保固件来自可信的厂商

3.3.1 设备证书的颁发与烧录

在量产阶段,每个设备都需要一个唯一的身份证书。流程一般是:

  1. 设备在产线上生成自己的密钥对(私钥永不出设备)
  2. 设备生成证书签名请求(CSR),包含公钥和设备ID
  3. CSR发送到厂商的CA服务器
  4. CA验证设备身份后,签发设备证书
  5. 设备证书被烧录到设备的安全存储区(如eFuse或TPM)

我参与过一个智能电表项目,产线每天要烧录10万+设备。最开始用软件生成密钥对,速度慢不说,还容易受PC环境感染。后来改成硬件安全模块(HSM)批量生成,效率提升了20倍。

3.3.2 证书吊销:被忽视的环节

很多IoT厂商只关注证书颁发,却忘了证书吊销。一旦某个设备的私钥泄露,或者CA被攻破,没有吊销机制就等于敞开了大门。

常用的吊销方式有两种:

方式原理IoT适用性
CRL(证书吊销列表)CA定期发布被吊销证书的序列号列表设备需要联网下载,离线场景不适用
OCSP(在线证书状态协议)实时查询某个证书是否被吊销需要网络连接,延迟较高
短有效期证书证书有效期只有几天或几小时适合高安全场景,但需要频繁更新

我个人比较推荐在IoT设备上用短有效期证书+定期轮换的策略。这样即使某个证书泄露,攻击者也只能在很短时间内利用它。

注意: 我曾经见过一个厂商,设备证书有效期设了10年。结果第3年私钥泄露,他们只能召回所有设备重新烧录。成本高得吓人。现在我的设计原则是:证书有效期不超过1年,最好3~6个月。

3.4 知识体系总览

下面这张图把本章的核心逻辑串起来了。你可以看到,从数字签名到证书链,再到PKI体系,是一条完整的信任链路。

数字签名与PKI知识体系 数字签名与PKI知识体系 数字签名 RSA-PSS / ECDSA X.509证书 身份 + 公钥 + CA签名 证书链 根CA → 中间CA → 设备 公钥基础设施(PKI) CA颁发 | CRL吊销 | OCSP查询 | 密钥管理 设备身份认证 TLS握手 / 设备准入 固件安全更新 签名验证 / 防回滚 安全通信 TLS 1.3 / DTLS 核心逻辑:签名保证数据完整性 → 证书保证公钥真实性 → PKI保证信任可管理 三者缺一不可,构成IoT设备安全启动的信任基石

3.5 实战中的几个关键决策

讲完理论,咱们聊聊落地时我常遇到的几个选择题。

3.5.1 选RSA还是ECDSA?

我的建议很简单:

  • 如果设备有硬件加速(比如ARM CryptoCell),优先用ECDSA P-256。速度快,密钥短。
  • 如果设备没有硬件加速,且主频很低(比如几十MHz的MCU),RSA-2048的验签速度反而可能比ECDSA快。因为RSA验签只需要公钥指数(通常是65537),计算量小。
  • 如果考虑未来抗量子攻击,可以提前布局基于哈希的签名(如XMSS),但那是另一个话题了。

3.5.2 证书存在哪?

绝对不要存在普通Flash里。攻击者可以轻松读取和篡改。我习惯的做法:

  • 私钥:放在安全元件(SE)或TPM里,永远不导出
  • 设备证书:可以放在外部Flash,但必须用哈希锁定或加密存储
  • 根证书:烧录在一次性可编程存储器(OTP/eFuse)里,不可更改
一个小技巧: 我在一个项目里把根证书的哈希值烧在eFuse里,证书本身放Flash。每次启动时先算Flash里证书的哈希,跟eFuse里的比对。这样既节省了eFuse空间,又保证了根证书的完整性。

3.5.3 离线设备怎么办?

很多IoT设备部署后就没网了。这时候CRL和OCSP都用不了。我的方案是:

  • 在固件更新包里附带最新的CRL
  • 设备在更新固件时,先更新CRL,再验证新固件签名
  • 如果设备永远不更新,那就只能靠短有效期证书+物理防篡改来降低风险