证书还没过期,域名也对,OpenSSL却报certificate revoked。先别急着补fullchain:error 23指向吊销检查,不是普通的缺链。本文用隔离根CA、中间CA和叶证书,复现叶子与中间证书被吊销的差异,再把序列号、CRL来源和部署验收串起来。
一、error 23不是进程退出码23
OpenSSL验证错误23对应certificate revoked;depth指出出错证书在所构建路径中的位置,叶子通常为0,直接签发者为1。本轮OpenSSL 1.1.1k FIPS的verify失败退出2,不是23。自动化要同时保存错误号、depth和进程退出码。
证书有效期像门票日期,吊销状态则像一张已被作废的票:日期还在范围内,不代表可以继续使用。也不要把error 23与error 3混为一谈,后者在本文夹具中表示找不到所需CRL。
二、先绑定证书,再读取吊销列表
在受控工作目录保留原始证书与CRL,不覆盖现场文件。leaf.pem为待验叶证书,intermediate.pem为其签发者,root.pem是独立授权的信任根。issuer.crl.pem是中间CA签发的PEM格式CRL;文件名只是本文约定,不表示它自动可信。
openssl version openssl x509 -in leaf.pem -noout -subject -issuer -serial -dates openssl crl -in issuer.crl.pem -noout -issuer -lastupdate -nextupdate openssl crl -in issuer.crl.pem -noout -text核对证书issuer、serial与CRL issuer、时间以及条目。序列号只在同一签发者范围内识别证书,不能把另一CA的相同数字当成同一张证书;十六进制显示差异也不能只靠字符串包含判断。
这些命令用于读取材料,不证明CRL签名正确、适用范围正确或当前有效。仅见到某个序列号,不能跳过验证就宣布生产证书已吊销。复杂的间接CRL、分区或增量CRL另按其扩展处理,本文只实验普通完整CRL。
三、显式开启检查,才知道当前策略验了什么
下面固定信任、构链、服务端用途与主机名,并用-crl_check检查叶证书吊销状态。-CRLfile加载本地列表,不能把它理解为从证书分发点自动下载;本轮没有联网获取CRL,也没有测试浏览器策略。
openssl verify -trusted root.pem -untrusted intermediate.pem \ -purpose sslserver -verify_hostname app.example.test \ -crl_check -CRLfile issuer.crl.pem leaf.pem本轮把叶证书序列号写进有效、正确签名的CRL后,这条命令报error 23 at 0 depth,退出2。相同材料不启用吊销检查时,普通链验证仍可通过。后者不是修好了,只是没有执行同一项检查。
不要通过去掉-crl_check、关闭验证或放宽错误处理消除告警。先核实输入确为当前目标证书,再向签发方确认吊销事件与原因。CRL签名和时间通过也只说明列表可用于相应检查,不意味着叶证书没有条目。
四、中间CA被吊销,叶子检查可能仍通过
第二组实验保持叶子未吊销,仅把中间CA序列号加入根CA签发的CRL。叶子级-crl_check通过;改用-crl_check_all并提供所需列表后,在depth 1报error 23。这里的问题是路径上的中间CA,重签一张仍走同一路径的叶证书未必能解决。
openssl verify -trusted root.pem -untrusted intermediate.pem \ -purpose sslserver -verify_hostname app.example.test \ -crl_check_all -CRLfile all-crls.pem leaf.pemall-crls.pem在本轮由中间CA与根CA签发的两份PEM CRL组成,必须先分别核验来源与适用范围。全路径检查只给叶子签发者CRL会在depth 1报error 3;这与真正识别中间CA已吊销是不同结论。不要见到all就以为工具自动补齐了资料。
五、隔离对照:把“不查”“查不到”“已吊销”分开
以下结果来自临时目录生成的RSA测试链,未修改系统时钟、信任库或生产服务;测试材料已清理。空CRL指有有效签名且零条目的列表,不是空文件。版本不同应重新跑正反例,不把本机结果推广成所有客户端行为。
| 材料与检查方式 | 本轮结果 | 结论边界 |
|---|---|---|
| 叶子已吊销,不启用CRL检查 | 链验证通过 | 未验吊销,不是修复 |
| 叶子已吊销,crl_check | 23 / depth 0 | 叶子吊销命中 |
| 中间CA已吊销,仅crl_check | 通过 | 只查叶子不足 |
| 中间CA已吊销,crl_check_all | 23 / depth 1 | 需处理签发路径 |
| 全路径检查缺根签发CRL | 3 / depth 1 | 补齐适用列表 |
| 叶子CRL过期 | 12 / depth 0 | 不能当成有效无吊销证明 |
错误签名列表还会导致CRL验证失败;不能靠编辑文本删除条目,改完也不再具有CA的有效签名。证书和CRL都可能暴露内部名称或序列信息,分享排障记录前仍要脱敏。
六、脚本验收不能只看最后一行OK
下面以全部所需列表已准备好为前提,直接保留verify退出状态。日志路径必须由任务身份控制,避免并发覆盖和不可信软链接。日志打不开同样阻断,不能把空日志解释为“没有错误”。
umask 077 rc=0 openssl verify -trusted root.pem -untrusted intermediate.pem \ -purpose sslserver -verify_hostname app.example.test \ -crl_check_all -CRLfile all-crls.pem leaf.pem \ >verify.log 2>&1 || rc=$? [ "$rc" -eq 0 ] || exit "$rc" printf '%s\n' '当前材料的离线CRL校验通过'本轮对包装器覆盖有效空列表、叶子吊销、中间CA吊销、缺列表、错误主机名和日志写入失败,成功提示只在通过时出现。不要管道接tee后只读取tee的退出码;也不要用单项openssl crl能读取或签名检查成功替代整条路径验证。
七、替换证书后,仍要验真实终点
确认吊销后按签发方流程处理原因;若涉及密钥泄露,应轮换密钥而不是照旧复用。中间CA被吊销则需采用获准的新签发路径,不能擅自把它加进信任库来绕过问题。
部署后分别核对实际终点返回的证书、签发者、序列号、公钥、SAN和链,再按目标客户端的吊销策略与业务请求验收。本文离线通过不证明HTTPS已上线,也不证明所有浏览器都采取相同CRL行为;CDN和多节点仍需逐点检查。
- 绑定错误号、depth、退出码与精确证书,未只凭域名认文件。
- CRL来源、签名、适用范围、时间和条目分别核验。
- 叶子与全路径检查范围明确,负例能阻断,日志失败不放行。
- 替换原因已处理,真实终点和客户端策略另行验收。
八、参考资料
- OpenSSL verify:CRL与证书路径验证
- OpenSSL crl:列表读取
- RFC 5280:证书与CRL规范
- CertbotX