跳转到主内容证书链 | 物联网民工

证书链

很多设备接入云平台时,会拿到一个 .crt.pem 文件,然后配置到 TLS、MQTT 或 HTTPS 客户端里。

这很容易让人以为“设备证书”就是一个文件。实际上证书只是信任链里可见的一段。真正要设计的是:设备怎样证明自己是谁,服务器怎样验证这个身份,设备私钥怎样生成和保存,证书过期或泄露后怎样处理。

一条典型设备证书链是:

Root CA
-> Intermediate CA
-> Device Certificate
-> Device Private Key

服务器信任 Root CA 或某个中间 CA。设备连接时发出设备证书和必要的中间证书。服务器验证证书链、有效期、用途、设备身份字段,再用证书里的公钥验证设备是否持有对应私钥。

证书链解决的是“身份怎样被可信地绑定到公钥”,不是单纯的文件格式问题。

证书绑定的是身份和公钥

证书里最核心的内容是:

subject / SAN / device identity
public key
issuer
validity
key usage / extended key usage
signature

CA 用自己的私钥给这些内容签名。验证方用 CA 公钥验签,确认“这个公钥和这个身份声明确实由可信 CA 签发”。

设备证书通常用来表达:

  • 设备序列号
  • 设备 ID
  • 产品型号
  • 租户或项目归属
  • 设备公钥
  • 证书有效期
  • 设备认证用途

这里最重要的不是字段看起来像什么,而是服务器端是否明确知道该从哪个字段取设备身份,并且这个字段是否被证书签名保护。

现代 TLS 里通常不建议继续依赖 CN 作为主身份字段,更常见的是使用 SAN,或者在私有 PKI 中明确约定 subject、SAN URI、SAN DNS、SAN otherName 里的设备身份表达方式。

私钥才是设备身份的根

证书是公开材料,可以发给服务器,也可以被别人看到。证书泄露本身通常不等于设备被冒充。

真正敏感的是设备私钥。

设备证明身份时,本质上是在握手中证明:

我持有这张证书对应公钥的私钥

所以设备证书体系的安全边界取决于私钥保护:

  • 私钥是不是在设备端生成
  • 私钥有没有离开过设备
  • 私钥是否以明文放在 flash
  • 调试口是否能读出私钥
  • 固件日志是否会打印私钥或证书包
  • 产线工具是否批量保存私钥
  • 设备恢复出厂是否会错误复用或覆盖私钥

如果所有设备共用同一把私钥和同一张证书,一台设备泄露就会影响整批设备。设备身份应该尽量是一机一证、一机一私钥。

Root CA、Intermediate CA 和设备证书分工不同

Root CA 是信任锚。它通常长期保存,离线管理,尽量少用。

Intermediate CA 用来签发设备证书。它可以按产品线、区域、客户、产线或批次拆分。

Device Certificate 是发给单台设备的身份凭据。

Root CA:        信任根,生命周期长,保护强
Intermediate:  签发设备证书,可分域管理
Device Cert:   单设备身份,随设备部署
Device Key:    单设备私钥,不能泄露

这种分层的价值在于隔离风险。某条产线的中间 CA 出问题,不应该立刻牵连所有产品线。设备证书泄露,也不应该影响其他设备。

不要把 Root CA 私钥放进产线脚本、构建机或云端普通服务里。Root CA 私钥一旦泄露,整套信任体系就需要重建。

证书链校验不是只看签名

验证设备证书时,不能只检查“签名是否能验过”。

至少还要检查:

  • 链路是否能追溯到受信任 CA
  • 每级证书是否在有效期内
  • CA 证书是否真的有 CA 权限
  • 设备证书用途是否允许客户端认证
  • 签名算法和密钥长度是否符合策略
  • 设备身份字段是否符合业务记录
  • 证书是否被吊销或禁用
  • 主机名或设备 ID 是否匹配预期

在 mTLS 场景里,服务器验证客户端证书后,还要把证书中的身份映射到业务设备记录:

certificate SAN / subject
-> device_id
-> product / tenant / policy
-> authorization

TLS 只完成密码学验证。设备能不能访问某个 topic、API 或资源,还需要业务授权层判断。

时间对证书系统很敏感

证书有 notBeforenotAfter。验证方需要可靠时间来判断证书是否生效、是否过期。

服务器通常有可靠时间,问题相对小。设备端验证服务器证书时更麻烦:

  • 设备没有 RTC
  • RTC 电池没电
  • 刚启动还没 NTP
  • 出厂时间是默认值
  • 离线环境无法校时

如果设备时间错误,可能出现两类问题:

  • 证书明明有效,但设备认为还没生效或已经过期
  • 过期或被替换的证书被错误接受

工程上常见做法包括:使用安全时间源,保存上次可信时间,等待网络校时后再建立敏感连接,或者在受控环境里设计专门的初次配网和时间引导流程。

不要简单关闭证书时间校验。那会让证书有效期失去意义。

吊销和轮换要提前设计

证书会过期,私钥会泄露,设备会返修,CA 也可能需要更换。

证书体系必须回答:

  • 设备证书过期前怎样更新
  • 私钥泄露后怎样禁用设备
  • CA 轮换时设备是否能信任新链
  • 离线设备重新上线后怎样处理旧证书
  • 服务器是否支持按设备禁用证书
  • CRL 或 OCSP 是否适合设备环境
  • 证书更新失败时设备是否会变砖

IoT 场景里,传统 Web PKI 的吊销机制不一定直接适用。设备可能长时间离线,网络受限,无法稳定访问 OCSP。很多系统会在服务端维护设备状态、证书指纹、序列号黑名单或设备禁用列表。

轮换也不能只靠“证书快过期再说”。设备要有安全更新路径,服务端要能同时接受新旧链一段时间,产线和售后系统也要知道新证书策略。

产线烧录是证书安全的一部分

设备身份通常在产线阶段创建或注入。

常见模式有两类。

第一,设备端生成密钥对:

device generates private key
-> exports public key / CSR
-> CA signs device certificate
-> device stores certificate

优点是私钥不离开设备。难点是产线流程更复杂,需要设备具备可靠 RNG 和 CSR/签发对接能力。

第二,产线或 HSM 生成密钥和证书,再注入设备:

HSM / provisioning system generates key pair
-> CA signs certificate
-> injects private key + certificate into device

优点是流程可控。难点是私钥会经过注入链路,必须保护传输、工站、日志、临时文件和权限。

无论哪种方式,都要避免:

  • 使用同一套证书镜像烧所有设备
  • 私钥出现在 CSV、日志、截图或产线报表里
  • 工站本地长期保存未加密私钥
  • 设备序列号和证书身份对不上
  • 烧录失败后设备进入半身份状态
  • 返工设备重复分配新身份但旧身份未禁用

产线不是安全体系之外的流程。它决定设备身份从哪里来。

证书不等于授权

设备证书能证明“这是某个设备身份持有的私钥”。它不自动说明这个设备能做什么。

授权通常要另外判断:

  • 设备属于哪个产品
  • 设备属于哪个租户
  • 是否已经激活
  • 是否被禁用
  • 是否允许访问某个 topic
  • 是否允许 OTA
  • 是否允许写配置

证书身份应该映射到服务端设备记录,而不是直接把证书通过等同于所有权限。

mTLS authenticated device_id
-> lookup device record
-> check tenant/product/status
-> apply policy

这也是为什么证书字段设计要稳定。字段一旦混乱,后面的授权、审计、吊销和运维都会变困难。

排查顺序

遇到设备 TLS 连接失败、云端拒绝证书、设备身份串号、证书过期或批量认证异常时,可以按这条链检查:

设备私钥是否和证书公钥匹配
-> 设备是否发送完整中间证书链
-> 服务端是否信任对应 Root/Intermediate CA
-> 证书有效期和系统时间是否正确
-> key usage / extended key usage 是否允许客户端认证
-> 设备身份字段是否和服务端记录一致
-> 证书序列号或指纹是否被禁用
-> 产线是否一机一证一私钥
-> 私钥是否可能从 flash、日志、调试口或工站泄露
-> CA 轮换策略是否已部署到服务端和设备端

设备证书链不是把 PEM 文件放到正确目录。它是一套把设备身份、公钥、私钥保护、CA 信任、生命周期和产线流程连接起来的工程系统。