密码学基础(下):公钥基础设施(PKI)、证书链、信任根
上一讲我们聊了对称与非对称加密、哈希和数字签名。这些工具单独用,其实挺脆弱的。你想想看——你拿到一个公钥,怎么确定它真的是设备厂商的?中间人完全可以伪造一对密钥,把自己的公钥塞给你。
这就是 PKI 要解决的问题。说白了,PKI 就是一套「谁说了算」的信任机制。我在做固件安全审计时,见过太多设备因为 PKI 部署不当,签名形同虚设。嗯,今天我们就把它彻底讲透。
PKI 的核心角色
PKI 不是单个技术,而是一套体系。它包含三个核心角色:
- 证书颁发机构(CA)——负责签发和吊销证书。它是信任的源头。
- 注册机构(RA)——负责验证申请者的身份。CA 通常不直接对接用户,RA 做初审。
- 终端实体——持有证书的设备或人。比如你的 IoT 设备、固件签名服务器。
我习惯把 CA 比作「身份证办理中心」,RA 是「派出所户籍窗口」,终端实体就是「你手里的身份证」。没有这套体系,你没法证明「你就是你」。
X.509 证书结构
固件签名中最常用的证书格式是 X.509 v3。一个证书长什么样?我拆开给你看:
| 字段 | 含义 | 我的备注 |
|---|---|---|
| 版本号 | 通常是 v3 | v3 才支持扩展项 |
| 序列号 | CA 分配的唯一编号 | 吊销时靠它定位 |
| 签名算法 | 如 SHA256-RSA | 别用 SHA1,已经废了 |
| 颁发者 | CA 的 DN(专有名称) | 链式验证的关键 |
| 有效期 | notBefore / notAfter | 过期证书直接拒掉 |
| 主体 | 证书持有者的 DN | 设备 ID 通常放这里 |
| 公钥 | 持有者的公钥 | RSA 2048+ 或 ECC P-256 |
| 扩展项 | Key Usage、Basic Constraints 等 | 我吃过亏,后面细说 |
| 签名值 | CA 对上述字段的签名 | 防篡改的最后一道锁 |
证书链与信任根
你不可能让每个设备都内置所有 CA 的公钥。现实做法是——设备只内置几个「信任根」,然后通过证书链逐级验证。
举个例子。你的 IoT 设备里烧录了 Root CA 的公钥。固件签名用的是 Intermediate CA 签发的代码签名证书。验证流程是这样的:
- 设备收到固件包,附带签名值和签名证书。
- 设备用内置的 Root CA 公钥,验证 Intermediate CA 证书的签名。
- 验证通过后,用 Intermediate CA 的公钥,验证代码签名证书的签名。
- 最后用代码签名证书的公钥,验证固件哈希的签名值。
每一步都环环相扣。只要有一环断了,信任就崩塌。
证书链的 SVG 结构图
下面这张图展示了典型的固件签名证书链。我建议你仔细看箭头方向——验证是从下往上,签名是从上往下。
证书吊销:被遗忘的防线
证书会过期,也会被泄露。一旦私钥泄露,你必须能及时吊销证书。常用的吊销机制有两种:
- CRL(证书吊销列表)——CA 定期发布一个黑名单。设备下载后比对。缺点是实时性差,列表会越来越大。
- OCSP(在线证书状态协议)——设备实时向 OCSP 服务器查询证书状态。实时性好,但需要网络连接。
固件签名中的 PKI 最佳实践
做了这么多年嵌入式安全,我总结了几条铁律:
- 根 CA 离线保存——根 CA 私钥永远不要联网。签中间 CA 证书时,用一台断网的专用机器操作。我见过有人把根 CA 私钥放在构建服务器上——嗯,那跟没锁门一样。
- 分层管理密钥——根 CA、中间 CA、代码签名证书,三级分离。即使代码签名证书泄露,你只需要吊销它,根和中间 CA 不受影响。
- 证书有效期要短——代码签名证书建议 1-2 年。中间 CA 不超过 5 年。根 CA 可以 10-20 年,但私钥保护级别要最高。
- 设备端做完整链验证——不要只验证叶子证书。我见过不少设备只检查固件签名证书的有效期,却不验证它是否由受信任的 CA 签发——这等于没验。
- 硬编码信任根要谨慎——信任根的公钥哈希要烧死在芯片的 eFuse 或安全存储里。别放在文件系统里,那太容易被替换了。
实际部署中的常见误区
我整理了几个高频翻车点,你对照看看自己的项目有没有中招:
| 误区 | 后果 | 正确做法 |
|---|---|---|
| 根 CA 私钥存储在构建机 | 一次入侵,整个信任体系崩塌 | 离线 HSM 或专用安全机器 |
| 证书链验证跳过中间 CA | 中间人可以用自签名证书冒充 | 逐级验证到信任根 |
| CRL 更新周期过长 | 吊销滞后,泄露的证书仍可用 | CRL 更新 ≤ 24 小时,配合 OCSP |
| 信任根可软件更新 | 攻击者替换信任根,签名形同虚设 | 信任根写死在一次性存储中 |
| 证书扩展项未检查 | 代码签名证书被用于 TLS 服务器 | 检查 Key Usage 和 Extended Key Usage |
PKI 这东西,搭建起来不难,但想搭得牢靠,细节特别多。你想想看——整个固件安全体系都建立在信任根不被篡改这个假设上。一旦这个假设破了,后面所有加密、签名、校验都是白搭。
我个人习惯在项目初期就画好证书链拓扑图,明确每个角色的职责和存储位置。别等到量产了才发现信任根烧录流程有漏洞——那时候改起来,成本就高了。