3、密码学基础(下):公钥基础设施(PKI)、证书链、X.509证书格式解析
3.1 为什么需要PKI?
上一节我们聊了非对称加密。你想想看,公钥是公开的,但你怎么确定这个公钥真的是张三的?
这就是PKI要解决的问题。说白了,PKI就是一套管理公钥的规则和设施。它解决三个核心问题:
- 身份认证:公钥到底是谁的?
- 完整性:公钥有没有被篡改?
- 不可否认性:对方能不能赖账?
我在做固件签名方案时,一开始觉得直接用RSA签名就够了。后来发现,没有PKI支撑,你根本没法安全地分发公钥。嗯,这里要注意,签名算法和公钥分发是两码事。
3.2 PKI的核心组件
PKI不是单个东西,而是一套体系。我习惯把它拆成这几个部分:
| 组件 | 作用 | 我踩过的坑 |
|---|---|---|
| CA(证书颁发机构) | 签发和管理证书 | CA的私钥一定要离线保存! |
| RA(注册机构) | 审核申请者身份 | RA和CA分离,安全第一 |
| 证书库 | 存储和分发证书 | LDAP目录服务器常用 |
| CRL/OCSP | 证书吊销状态查询 | OCSP响应器要扛得住并发 |
核心原则:CA的根私钥是整个PKI的信任锚点。一旦泄露,整个体系就崩了。
3.3 证书链——信任的传递
你想想看,如果每个设备都内置几百个CA证书,那得多麻烦?证书链就是解决这个问题的。
证书链的结构是这样的:
根CA(自签名证书)
└── 二级CA(由根CA签发)
└── 三级CA(由二级CA签发)
└── 终端实体证书(由三级CA签发)
验证过程是从下往上:
- 用三级CA的公钥验证终端证书的签名
- 用二级CA的公钥验证三级CA证书的签名
- 用根CA的公钥验证二级CA证书的签名
- 根CA自签名,信任它需要预置
实战经验:我曾经遇到一个客户,他们的设备只预置了根CA证书,但固件更新时只发了终端证书。结果验证链断了,因为设备没有中间CA证书。后来我建议他们要么把整个链发过去,要么预置所有中间CA。
3.4 X.509证书格式解析
X.509是证书的标准格式。我刚开始看的时候觉得挺复杂,其实拆开来看就清楚了。
一个典型的X.509 v3证书包含:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0x12345678
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=MyRootCA, O=MyCompany
Validity:
Not Before: Jan 1 00:00:00 2024 GMT
Not After : Dec 31 23:59:59 2025 GMT
Subject: CN=mydevice.example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Key Usage: critical
Digital Signature
Signature Algorithm: sha256WithRSAEncryption
签名值(一堆十六进制数据)
关键字段说明:
- Version:现在基本都是v3,支持扩展
- Serial Number:CA保证唯一,我习惯用时间戳+随机数
- Issuer/Subject:颁发者和持有者,用DN(Distinguished Name)表示
- Validity:有效期,别设太长,一年够了
- Extensions:扩展字段,很多安全策略靠它实现
注意:Basic Constraints扩展里的CA标志很关键。如果给终端证书设了CA:TRUE,那它就能签发其他证书。我曾经见过有人不小心把设备证书设成了CA证书,结果设备被攻破后,攻击者用它签了假证书。
3.5 证书验证流程
验证证书时,我一般按这个步骤来:
- 有效期检查:当前时间在Not Before和Not After之间
- 签名验证:用颁发者公钥验证证书签名
- 证书链验证:一直追溯到信任的根CA
- 吊销状态检查:查CRL或OCSP,看证书是否被吊销
- 扩展检查:Key Usage、Extended Key Usage等是否匹配
避坑指南:我曾经在固件签名验证中只做了第1、2步,没做吊销检查。结果有个离职员工的证书没及时吊销,他还能签名固件。从那以后,我把OCSP检查加到了验证流程里。
3.6 固件签名中的PKI实践
在固件签名场景下,我建议这样设计:
- 根CA:离线保存,只在签发中间CA时使用
- 代码签名CA:专门用于签名固件,可以设置较短的密钥长度
- 设备证书:每个设备一个,用于身份认证
签名流程:
1. 代码签名CA用私钥对固件哈希签名
2. 将签名值和代码签名CA证书一起打包
3. 设备用预置的根CA证书验证代码签名CA证书
4. 用代码签名CA的公钥验证固件签名
我的习惯:我会在固件包里放两个证书——代码签名CA证书和它的上级CA证书。这样设备只需要预置根CA证书就够了。而且我建议用ECC算法,密钥短,验证快,适合资源受限的嵌入式设备。
3.7 本章知识体系
下面这张图展示了PKI、证书链和X.509的关系:
这张图把PKI的层次结构、X.509证书的内部组成、以及信任链的验证方向都串起来了。我个人觉得,理解了这个图,PKI的核心思想就抓住了。
总结一下:PKI是公钥管理的骨架,证书链是信任传递的链条,X.509是证书的具体格式。三者缺一不可。做固件签名时,我建议先把这套体系搭好,再考虑具体算法实现。