3、密码学基础(下):公钥基础设施(PKI)、证书链、根证书与中间证书
好,咱们接着聊。上一节我们把非对称加密和哈希算法讲透了,这一节要聊的,是OTA升级里真正让「信任」落地的东西——PKI和证书链。
说实话,我刚入行那会儿,觉得证书这东西就是「加个壳」,没什么技术含量。直到有一次,我在一个车机项目里,因为证书链没配全,导致升级包在设备端死活验不过……嗯,从那以后,我再也不敢小看证书管理了。
3.1 什么是PKI?说白了就是「信任的骨架」
PKI,全称Public Key Infrastructure,公钥基础设施。名字挺唬人,其实核心就三件事:
- 谁来发证书?——CA(证书颁发机构)
- 证书长什么样?——X.509标准格式
- 怎么验证证书?——证书链校验
你想想看,OTA升级里,设备端拿到一个升级包,它怎么知道这个包是官方发的,还是黑客伪造的?靠的就是PKI这套信任体系。设备端不直接信任「公钥」,它信任的是「签发公钥的那个证书」。
核心观点:PKI的本质,是把「信任」从一个人传递到另一个人,从根CA一直传递到你的设备。
3.2 证书链:信任的传递链条
证书链,也叫信任链。我习惯把它理解成「介绍信」的层层传递。
举个例子:
- 根CA(比如GlobalSign)给自己签了一个证书,这叫自签名证书。它是信任的起点。
- 根CA给某个中间CA签了一个证书,证明「这个中间CA是我认可的」。
- 中间CA再给某个车企的OTA服务器签一个证书,证明「这个服务器是合法的」。
- 设备端拿到服务器证书,一路往上查,查到根证书,发现根证书在设备信任列表里——好,信任成立。
这就是证书链。每一级证书都包含上一级CA的签名,环环相扣。
我的经验:在嵌入式设备里,证书链的长度一般控制在3级以内(根→中间→终端)。太长了,设备端验签耗时太长,用户体验差。我曾经见过一个项目用了5级证书链,每次升级验签要花8秒……直接被客户投诉。
3.3 根证书:信任的「锚点」
根证书是整个PKI体系的基石。它没有上级,自己给自己签名。所以根证书的私钥一旦泄露,整个信任体系就崩塌了。
在OTA升级里,根证书通常预埋在设备的固件里。设备出厂时,就把根证书写死在安全存储区(比如eFuse或HSM里)。
这里有个关键点:根证书不能更新。或者说,更新根证书的成本极高。你想想看,如果根证书私钥泄露了,你得召回所有设备,重新烧录固件——这可不是闹着玩的。
避坑指南:我曾经在一个IoT项目里,客户要求把根证书放在文件系统里,方便后续OTA更新。我坚决反对。为什么?因为如果攻击者能篡改文件系统,他就能替换根证书,然后用自己的假证书签假升级包。根证书必须放在只读的安全存储里,这是底线。
3.4 中间证书:灵活性的关键
中间证书的存在,是为了解决一个实际问题:根证书太金贵了,不能天天拿它来签名。
你想,如果每次OTA升级都用根证书私钥签名,那私钥暴露的风险就大大增加。所以实际做法是:
- 根CA的私钥离线保存,甚至放在物理隔离的机房里。
- 日常签名用中间CA的私钥。
- 即使中间CA的私钥泄露,只要吊销中间证书,重新签发一个就行,根证书纹丝不动。
在OTA升级场景里,我建议至少使用两级证书:
| 层级 | 角色 | 私钥存储位置 | 使用频率 |
|---|---|---|---|
| 根证书 | 信任锚点 | 离线HSM或物理隔离 | 几乎不用 |
| 中间证书 | 日常签名 | 在线HSM或安全服务器 | 每次升级 |
| 终端证书 | 设备身份 | 设备安全存储 | 每次通信 |
3.5 证书格式:X.509到底长什么样?
X.509是证书的标准格式。你打开一个证书文件(通常是.pem或.der),里面包含:
- 版本号:目前主流是V3
- 序列号:CA分配的唯一编号
- 签名算法:比如SHA256-RSA
- 颁发者:签发这个证书的CA名称
- 有效期:起止时间
- 主体:证书持有者的信息
- 公钥:持有者的公钥
- 扩展字段:比如密钥用途、CRL分发点等
- 签名:CA用私钥对以上内容的签名
在嵌入式设备里,我们通常用DER格式(二进制),因为它解析快、体积小。PEM格式是Base64编码的,可读性好,但解析慢一些。
我的建议:在OTA升级场景里,证书文件尽量控制在2KB以内。有些设备的内存只有几十KB,一个4KB的证书就能把堆栈撑爆。我踩过这个坑,后来强制要求所有中间证书不超过1.5KB。
3.6 证书验证流程:设备端到底做了什么?
设备端收到升级包时,会附带一个签名和证书链。验证流程大致如下:
- 解析终端证书,提取公钥和签名算法。
- 用终端证书的公钥验证升级包的签名。如果失败,直接拒绝。
- 验证终端证书本身的合法性:用中间证书的公钥验证终端证书的签名。
- 验证中间证书的合法性:用根证书的公钥验证中间证书的签名。
- 检查根证书是否在设备的信任列表里。
- 检查所有证书的有效期、是否被吊销。
全部通过,信任建立。否则,升级包被丢弃。
小技巧:在设备端,我习惯把证书链的验证结果缓存起来。因为一次OTA升级可能要验证多个文件(比如bootloader、kernel、rootfs),每次都重新验证证书链太慢了。缓存有效期可以设为当前升级会话的时长。
3.7 证书吊销:信任的「撤回」机制
证书不是永远有效的。如果私钥泄露,或者CA发现某个证书被滥用,就需要吊销它。
常用的吊销机制有两种:
- CRL(证书吊销列表):CA定期发布一个列表,列出所有被吊销的证书序列号。设备端下载这个列表,验签后缓存起来。
- OCSP(在线证书状态协议):设备端实时向CA查询某个证书的状态。响应快,但需要网络连接。
在嵌入式设备里,我倾向于用CRL。因为OCSP需要设备联网查询,万一CA服务器挂了,升级就卡住了。CRL可以提前下载,离线验证。
避坑指南:我曾经在一个项目里,CRL文件太大(超过100KB),设备下载时内存不足。后来我改用增量CRL,只下载自上次更新以来新增的吊销记录。嗯,这个坑踩得值。
3.8 实战建议:OTA升级中的证书管理最佳实践
最后,我总结几条实战经验,供你参考:
- 根证书离线存储:永远不要把根证书私钥放在联网的服务器上。
- 证书链不超过3级:根→中间→终端,足够了。
- 证书有效期要合理:根证书10年,中间证书3年,终端证书1年。太长了不安全,太短了维护成本高。
- 支持证书轮换:设备端要能同时信任新旧两个根证书,方便平滑过渡。
- 日志记录:每次证书验证失败,都要记录详细原因(比如证书过期、签名不匹配、CRL命中)。这对排查问题太重要了。
好了,这一节的内容就到这儿。PKI和证书链是OTA升级安全的基石,理解透了,后面的签名方案、安全启动、防回滚等内容才能顺理成章。下一节,我们聊聊具体的签名算法选择和性能优化。