4. 证书验证原理:签名验证、有效期检查、撤销状态、策略约束
证书验证,说白了就是回答四个问题:这证书是谁签的?过期了没?被撤销了吗?用对地方了吗?
我刚开始做PKI运维的时候,总觉得验证就是检查一下有效期,直到有一次线上服务突然不可用,查了半天才发现——证书签名算法跟CA的不匹配,但有效期明明还在范围内。嗯,从那以后我再也不敢跳过完整的验证流程了。
下面这张图浓缩了整个证书链验证的核心环节,我建议你先瞄一眼,心里有个全局印象。
4.1 签名验证——真的还是假的?
签名验证是整个证书链的信任基石。CA用私钥给证书内容签名,客户端用CA公钥验签。说白了就是一道数学题:用公钥解一下签名,跟证书内容的摘要对比,一致就通过。
我个人习惯在巡检时先用OpenSSL跑一遍签名验证,看看会不会报错。下面这个命令我几乎每周都用:
# 验证终端证书的签名(假设CA证书和终端证书都在当前目录)
openssl verify -CAfile ca-cert.pem -verbose end-entity.pem
# 如果想看详细的签名算法信息
openssl x509 -in end-entity.pem -noout -text | grep "Signature Algorithm"
我在项目中遇到过一种情况:终端证书用的是RSA 2048位密钥,但CA在签发时用的摘要算法是SHA1,而客户端默认只信任SHA256以上。验签时OpenSSL虽然能通过,但Java应用直接就抛异常了。嗯,这种算法套件不匹配的坑,踩过一次就记住了。
4.2 有效期检查——别等过期了才慌
有效期检查是四个环节里最简单的,但也是出事故最多的。每张证书都有notBefore和notAfter两个时间戳,客户端会拿系统时间跟这两个时间做比较。系统时间不准,或者时区配错了,证书就"被过期"了。
我记得有一次一个金融客户的HTTPS证书突然报"不合法",排查了两小时,最后发现是服务器系统时间慢了整整一天。你想想看,证书本身没问题,但时间错了,整条链就断了。
我建议的巡检做法:
- 用
openssl x509 -in cert.pem -noout -dates查看起止时间 - 对比服务器系统时间(最好校准到NTP)
- 关注剩余有效期:我个人习惯提前30天预警,低于15天的直接走紧急换发流程
4.3 撤销状态检查——白名单之外的杀手
证书还在有效期内,不代表它就是安全的。密钥泄露、CA误签、域名变更,都可能导致证书被提前撤销。撤销状态检查有两种主流方式:CRL(证书撤销列表)和OCSP(在线证书状态协议)。
| 对比项 | CRL | OCSP |
|---|---|---|
| 工作原理 | CA定期发布撤销列表,客户端下载后离线检查 | 客户端实时向OCSP响应器查询证书状态 |
| 优点 | 不依赖网络,适合离线环境 | 实时性强,能秒级感知撤销 |
| 缺点 | 列表可能很大(几十MB),存在延迟窗口 | 依赖OCSP响应器可用性,可能成为单点故障 |
| 巡检要点 | 检查CRL的nextUpdate时间,是否快过期了 | 检查OCSP响应器的响应时间和可用率 |
我优化过一套OCSP响应器集群,当时响应时间在高峰期飙到500ms以上,应用层频繁超时回退到CRL。后来做了缓存分层和预取,把P99降到了50ms以内。巡检的时候我会刻意打几条查询,看响应时间和HTTP状态码,200和503的差别在线上就是生死之别。
- CRL分发点(CDP)地址是否能正常访问
- OCSP响应器地址是否合法(很多攻击会篡改OCSP URL指向恶意服务)
- 如果同时启用CRL和OCSP,策略上怎么兜底——我个人偏好OCSP为主、CRL为备
4.4 策略约束——最后一层"门禁"
策略约束是四个环节里最容易被忽略的。CA可以给证书加上各种策略限制,比如:这张证书只能用于代码签名,不能用于TLS;或者这个下级CA只能签发域名在*.example.com内的证书。
我记得有一次排查一个证书链验证失败的问题,所有基本检查都过了——签名OK、有效期OK、撤销状态也OK,但就是报"policy constraint violation"。最后发现是上级CA在证书里加了PolicyConstraints: requireExplicitPolicy,而下级证书里没有声明任何策略OID。
策略约束的常见类型:
- 证书策略(Certificate Policies): 声明证书的用途范围,用OID标识
- 策略映射(Policy Mappings): 允许下级CA把上级的策略映射成自己的策略
- 名称约束(Name Constraints): 限制下级CA只能签发特定域名或DN范围的证书
- 关键用法(Key Usage / Extended Key Usage): 限制密钥的具体用途
巡检时我一般会这样检查策略约束:
# 查看证书策略和约束
openssl x509 -in cert.pem -noout -text | grep -A 20 "Certificate Policies"
openssl x509 -in cert.pem -noout -text | grep -A 10 "Policy Constraints"
openssl x509 -in cert.pem -noout -text | grep -A 10 "Name Constraints"
# 如果策略不匹配,openssl verify 会明确报错
openssl verify -CAfile ca.pem -policy_check -verbose end.pem
四个环节都走通了,证书链才算真正可信。我每次做完一轮巡检,都会在报告里把这四个状态用红绿灯图标标出来——红灯一个都不能有,黄灯要写清楚风险,绿灯才敢签字归档。