PKI与证书体系
在做OCSP异常检测之前,你必须先搞清楚一个底层问题:证书到底是怎么信任的?说白了,整个HTTPS、代码签名、邮件加密,背后都靠PKI这张大网撑着。
我当年刚接触PKI时,觉得这东西就是个“CA发证书”的简单流程。直到有一次排查线上TLS握手失败,才发现证书链、CRL、OCSP这三者配合不好,能让你排查到怀疑人生。今天咱们就把这张网拆开揉碎。
公钥基础设施构成
PKI不是单一软件,是一套人+流程+技术的组合。记住下面这几个核心角色就行:
- 证书颁发机构(CA) – 签发和撤销证书的“权威法院”。
- 注册机构(RA) – 负责验证申请者身份,把审核结果告诉CA。
- 证书库(Repository) – 存放已签发证书和CRL的地方,通常用LDAP或HTTP。
- 证书持有者(End Entity) – 拿着证书的人或设备,比如你的浏览器或服务器。
- 依赖方(Relying Party) – 需要验证证书的人,比如你浏览器在访问HTTPS网站时。
你想想看,这五个角色配合起来,才形成一个完整的信任闭环。我在某电商公司审计时,发现他们RA环节几乎没人管,身份验证全凭邮件确认,结果被中间人伪造了证书。嗯,后来我们强制加了视频验证和生物特征,才算堵上漏洞。
X.509证书结构
RFC 5280定义的X.509 v3证书,说白了就是一个结构化的数据包。你用openssl x509 -text一看,里面字段至少二十多个。但关键的就这几块:
| 字段 | 典型内容 | 我的踩坑提醒 |
|---|---|---|
| 版本号 | v3(0x02) | 要是v1或v2,基本是老古董,别用。 |
| 序列号 | CA生成的唯一号码 | 我曾经碰到过序列号重复,那家CA的数据库废了。 |
| 签名算法 | sha256WithRSAEncryption | 如果写md5或sha1,立即报警。 |
| 颁发者(Issuer) | C=CN, O=某CA, CN=Root CA | 注意拼写错误,我见过Issuer和Subject拼反的。 |
| 主体(Subject) | C=US, O=Google, CN=*.google.com | 通配符证书不能滥用,我见过*.*.com这种荒唐写法。 |
| 有效期 | notBefore / notAfter | 过期证书是OCSP日志里的常客。 |
| 公钥 | RSA 2048 / ECC P-256 | 密钥长度低于2048的,我建议直接拒绝。 |
| 扩展 | Key Usage, Extended Key Usage, Subject Alt Name等 | 扩展缺失会导致证书被滥用,比如把服务端证书当代码签名用。 |
有一个细节我特别在意:授权密钥标识符(Authority Key Identifier)。它指向颁发者的Subject Key Identifier,是构建证书链的关键线索。你要是用openssl验证时提示“unable to get local issuer certificate”,多半是这个字段对不上。
CRL vs OCSP:离线PKI vs 在线PKI
证书被吊销(比如私钥泄露、员工离职),必须让依赖方知道。传统方案是证书吊销列表(CRL),现代方案是在线证书状态协议(OCSP)。两者的区别,我用一张表说清楚:
| 对比项 | CRL | OCSP |
|---|---|---|
| 数据获取方式 | 定时下载整张列表 | 实时查询单张证书 |
| 网络请求 | 1次请求拿到所有吊销证书 | 每张证书都要单独查询 |
| 时效性 | 取决于CRL更新周期(可能数天) | 实时响应(通常秒级) |
| 隐私性 | 不暴露查询哪个证书 | 服务器能看到你在查谁(所以出现OCSP stapling) |
| 流量开销 | 列表可能几MB,对移动端不友好 | 请求响应几十字节,非常轻量 |
| 服务器负载 | CDN扛得住,但更新是全量 | 并发高时容易打爆OCSP响应器 |
我在银行做审计时,亲眼见过一个CA的CRL更新频率是每周一次。周二私钥泄露,直到下周一才被吊销,中间五天黑客拿了证书乱签名。从那以后,我强烈建议所有生产环境必须启用OCSP,并且配合Must-Staple扩展。
证书链验证过程
验证一个终端证书是否可信,不是只看它本身,而是要沿着证书链一直追到信任锚点(通常是预置在操作系统或浏览器里的根证书)。流程很简单,但坑很多:
- 构建链 – 从终端证书开始,根据Issuer字段找到签发者证书,再往上,直到一个自签名根证书或你信任的锚点。
- 验证签名 – 每一级都用上一级的公钥验证下一级的签名。签名不匹配,直接报错。
- 检查有效期 – 每一张证书的notBefore/notAfter必须包含当前时间。注意:根证书通常长期有效,中间证书可能就2-3年。
- 检查吊销状态 – 可以用CRL或OCSP查询每张证书(除了根证书,因为它自签名且无上级吊销它)。
- 检查关键扩展 – 比如Basic Constraints必须标识CA权限,Key Usage必须包含keyCertSign等。
这里有个容易忽视的点:证书链不一定只有一条路径。比如同一张终端证书可能被两个不同的CA签发(交叉认证)。我曾经在排查一个SSL握手失败时,发现客户端只带了一条链,而服务器信任的根在另一条链上,花了三小时才定位到。后来我写了个脚本,每次部署前自动打印所有可能的Certificate Path。
下面这张图总结一下PKI的完整体系,也是我们做OCSP日志异常检测时必须刻在脑子里的结构:
有了这张图,再看OCSP日志就好办了。你每天会看到大量依赖方→OCSP响应器的请求:状态、时间、证书序列号、响应签名。我们后续课程就是要从这些日志里抓出“状态异常”、“响应延迟”、“伪造响应”等特征。
最后说一句:了解PKI不是为了考试,而是为了看懂异常。你在日志里看到“Unknown CA”或者“Certificate has expired”,如果脑子里立刻能浮现出上面那张图和证书结构,定位速度至少快一倍。