很多设备接入云平台时,会拿到一个 .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 或资源,还需要业务授权层判断。
时间对证书系统很敏感
证书有 notBefore 和 notAfter。验证方需要可靠时间来判断证书是否生效、是否过期。
服务器通常有可靠时间,问题相对小。设备端验证服务器证书时更麻烦:
- 设备没有 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 信任、生命周期和产线流程连接起来的工程系统。