3、OpenSSL生成CRL:命令行实战与签名验证
好,咱们进入实操环节。前面两章把CRL的理论和数据结构讲清楚了,这一章我带你直接用OpenSSL命令行把CRL生成出来、看明白、再验一遍签名。说白了,就是让你亲手摸到CRL长什么样。
我个人习惯在测试环境里先跑通一遍,再上生产。你想想看,万一生产上把CA私钥路径写错了,吊销列表发出去没人认,那可就尴尬了。嗯,咱们先从最基础的开始。
3.1 准备工作:你得有个CA
生成CRL之前,你手里必须有一个CA证书和对应的私钥。如果你还没有,可以用下面这条命令快速创建一个测试用的自签名CA:
# 生成CA私钥
openssl genrsa -out ca-key.pem 2048
# 生成自签名CA证书(有效期10年)
openssl req -x509 -new -nodes \
-key ca-key.pem \
-days 3650 \
-out ca-cert.pem \
-subj "/CN=Test CA/O=MyOrg/C=CN"
3.2 生成第一份CRL
有了CA,我们就可以生成CRL了。OpenSSL生成CRL的核心命令是 openssl ca -gencrl。看下面这个例子:
openssl ca -gencrl \
-config /etc/pki/tls/openssl.cnf \
-keyfile ca-key.pem \
-cert ca-cert.pem \
-out crl.pem
这条命令执行后,你会得到一个PEM格式的CRL文件。我刚开始用的时候,经常忘记指定 -config 参数,结果OpenSSL报错说找不到默认配置。嗯,这里要注意,-config 指向的配置文件里必须包含CA相关的路径设置。
如果你想指定CRL的有效期,可以用 -crldays 或 -crlhours 参数:
# 设置CRL有效期为30天
openssl ca -gencrl \
-config /etc/pki/tls/openssl.cnf \
-keyfile ca-key.pem \
-cert ca-cert.pem \
-crldays 30 \
-out crl-30days.pem
3.3 查看CRL内容
生成完CRL,你得看看里面到底写了什么。用 openssl crl 命令可以查看:
# 查看CRL的文本内容
openssl crl -in crl.pem -text -noout
输出结果大致长这样:
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: /CN=Test CA/O=MyOrg/C=CN
Last Update: Apr 1 12:00:00 2025 GMT
Next Update: May 1 12:00:00 2025 GMT
CRL extensions:
X509v3 Authority Key Identifier:
keyid:AB:CD:EF:...
X509v3 CRL Number:
1
Revoked Certificates:
Serial Number: 1234
Revocation Date: Mar 15 10:30:00 2025 GMT
Serial Number: 5678
Revocation Date: Mar 20 14:00:00 2025 GMT
我来帮你拆解一下这些字段:
| 字段 | 含义 | 我的经验 |
|---|---|---|
| Version | CRL版本,目前基本都是v2 | v1已经很少见了,别用 |
| Signature Algorithm | 签名算法,必须和CA证书一致 | 我建议用sha256WithRSAEncryption |
| Issuer | 签发者DN,必须和CA证书的Subject一致 | 这里不一致会导致验证失败 |
| Last Update / Next Update | CRL的生效时间和过期时间 | Next Update是客户端检查的关键 |
| CRL Number | CRL的序列号,每次更新递增 | 客户端可以用它判断CRL是否最新 |
| Revoked Certificates | 被吊销的证书序列号列表 | 每个条目都有吊销时间 |
Next Update 字段是客户端判断CRL是否过期的依据。如果客户端发现当前时间超过了 Next Update,它会认为CRL已失效,通常会拒绝所有该CA签发的证书。所以,一定要保证CRL的更新频率快于它的有效期。
3.4 验证CRL签名
CRL是CA签发的,所以它必须能被CA证书的公钥验证通过。验证命令很简单:
# 验证CRL签名
openssl crl -in crl.pem -CAfile ca-cert.pem -noout
如果签名验证通过,命令不会有任何输出(静默成功)。如果验证失败,你会看到类似这样的错误:
verify error:num=7:error:7FFF:CRL signature failure
为什么会失败?我遇到过几种情况:
- CA证书不匹配:你用的CA证书和签发CRL的CA不是同一个。检查Issuer字段是否一致。
- CRL被篡改:有人手动修改了CRL文件。签名会直接报错。
- 算法不匹配:CA证书的签名算法和CRL的签名算法不一致。比如CA用sha256,CRL用sha1。
openssl crl -in crl.pem -inform PEM -outform DER -out crl.der 转成DER格式,然后用十六进制工具看看原始数据。我曾经用这个方法发现过CRL里混入了多余的空格字符。
3.5 核心流程:从CA到CRL的完整链路
下面这张图展示了CRL生成和验证的完整流程,我建议你仔细看看:
3.6 批量吊销与CRL更新
实际工作中,你不会只吊销一两个证书。我建议你维护一个吊销索引文件,每次吊销证书时往里面追加记录。OpenSSL默认使用 index.txt 来管理吊销状态。
吊销证书的命令:
# 吊销证书(需要证书文件)
openssl ca -revoke cert-to-revoke.pem \
-config /etc/pki/tls/openssl.cnf \
-keyfile ca-key.pem \
-cert ca-cert.pem
吊销后,重新生成CRL:
# 生成包含最新吊销信息的CRL
openssl ca -gencrl \
-config /etc/pki/tls/openssl.cnf \
-keyfile ca-key.pem \
-cert ca-cert.pem \
-crldays 14 \
-out crl-updated.pem
3.7 本章小结
这一章我们亲手用OpenSSL生成了CRL,查看了它的内部结构,还验证了签名。你想想看,整个过程其实不复杂,但每一步都有坑。我个人建议你把上面的命令在测试环境里跑一遍,看看输出结果,再故意改一下CRL文件试试签名验证会不会报错。只有亲手踩过坑,才能真正记住。