You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

吊销客户端证书并更新CRL失败:生成空CRL且报错求助

CA证书吊销流程报错及CRL生成异常排查与修复

问题描述

编写Bash脚本用于创建带CRL的CA、生成客户端证书并执行吊销操作,但执行后出现报错:

cannot lookup how long until the next CRL is issued

生成的client/svc/ca/crl/revoked.crl为空,原CRL未记录任何吊销信息。相关脚本及配置文件如下:

执行脚本

#!/usr/bin/env bash
set -xeuo pipefail

SERVICE=svc
CA_DIR=client/$SERVICE/ca

# Create CA
mkdir -p "$CA_DIR"
touch "$CA_DIR/ca.index"
openssl rand -hex 16 > "$CA_DIR/ca.serial"

openssl genpkey -algorithm RSA -aes-256-cbc -out "$CA_DIR/ca.key" -pkeyopt rsa_keygen_bits:4096
chmod 400 "$CA_DIR/ca.key"

openssl req -new -out "$CA_DIR/ca.crt" -config "$CA_DIR/ca.conf" -x509 -days 365 -key "$CA_DIR/ca.key"

openssl x509 -in "$CA_DIR/ca.crt" -out "$CA_DIR/ca.pem" -outform PEM

CRL_DIR="$CA_DIR/crl"
mkdir -p "$CRL_DIR"
touch "$CRL_DIR/index.txt"
echo 00 > "$CRL_DIR/number"

openssl ca -gencrl -keyfile "$CA_DIR/ca.key" -cert "$CA_DIR/ca.crt" -out $CRL_DIR/crl.pem -config "$CRL_DIR/crl.conf"

# Create user certificate
USER=alice
CRT_DIR=client/$SERVICE/$USER

mkdir -p "$CRT_DIR"

## Create a new certificate
openssl req -new -nodes -newkey rsa:4096 -keyout "$CRT_DIR/client.key" -out "$CRT_DIR/client.csr" -config "$CRT_DIR/client.conf"

## Sign it with our CA
openssl ca -config "$CA_DIR/ca.conf" -cert "$CA_DIR/ca.crt" -keyfile "$CA_DIR/ca.key" -out "$CRT_DIR/client.crt" -infiles "$CRT_DIR/client.csr"

## Export client key
openssl pkcs12 -export -clcerts -in "$CRT_DIR/client.crt" -inkey "$CRT_DIR/client.key" -out "$CRT_DIR/client.p12"
openssl pkcs12 -in "$CRT_DIR/client.p12" -out "$CRT_DIR/client.pem" -clcerts

echo "Browser key: $PWD/$CRT_DIR/client.p12"
echo "PEM key: $PWD/$CRT_DIR/client.pem"

# revoke
CRT_FILE=$CRT_DIR/client.pem
openssl ca -config "$CA_DIR/ca.conf" -cert "$CA_DIR/ca.crt" -keyfile "$CA_DIR/ca.key" -revoke "$CRT_FILE"
openssl ca -config "$CA_DIR/ca.conf" -cert "$CA_DIR/ca.crt" -keyfile "$CA_DIR/ca.key" -gencrl -out "$CA_DIR/crl/revoked.crl"

配置文件

client/svc/alice/client.conf

[ req ]
default_bits = 4096
encrypt_key = no
default_md = sha256
string_mask = utf8only
utf8 = yes
prompt = no
req_extensions = req_ext
distinguished_name = distinguished_name

[ req_ext ]
basicConstraints = CA:false

keyUsage = keyEncipherment, digitalSignature

[ distinguished_name ]
commonName = alice client certificate for my.svc

[ alt_names ]

client/svc/ca/ca.conf

[ req ]
default_bits = 4096
encrypt_key = yes
default_md = sha256
string_mask = utf8only
utf8 = yes
prompt = no
x509_extensions = x509_ext
distinguished_name = distinguished_name

[ x509_ext ]
basicConstraints = critical, CA:true
nameConstraints = critical, @name_constraints
subjectKeyIdentifier = hash
issuerAltName = issuer:copy
authorityKeyIdentifier = keyid:always, issuer:always

keyUsage = keyCertSign, cRLSign

[ distinguished_name ]
commonName = svc client Root Certificate Authority

[ ca ]
default_ca = CA_default

[ CA_default ]
base_dir = client/svc/ca
database = $base_dir/ca.index
serial = $base_dir/ca.serial
new_certs_dir = client/svc/ca
crl = crl.pem
crl_dir = crl
default_md = sha256
default_days = 365
email_in_dn = no
policy = server_policy
copy_extensions = copy
uniqueSubject = no

[ server_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ ca_policy ]
countryName = supplied
stateOrProvinceName = supplied
localityName = supplied
organizationName = supplied
organizationalUnitName = optional
commonName = supplied
emailAddress = supplied

[ name_constraints ]
permitted;DNS.0 = my.local

client/svc/ca/crl/crl.conf

[ ca ]
default_ca = CA_default

[ crl_ext ]
authorityKeyIdentifier=keyid:always,issuer:always

[ distinguished_name ]
commonName = svc client Root Certificate Authority CRL

[ CA_default ]
base_dir = client/svc/ca/crl
crl = $base_dir/crl.pem
crlnumber = $base_dir/number
database = $base_dir/index.txt
default_crl_days = 30
default_md = default
default_days = 365

流程遗漏点及修复方案

1. CA配置缺失CRL核心参数

原ca.conf的CA_default段缺少CRL编号、默认有效期及扩展配置,导致生成CRL时无法读取必要元数据。修改ca.conf的CA_default段,并添加CRL扩展配置:

[ CA_default ]
base_dir = client/svc/ca
database = $base_dir/ca.index
serial = $base_dir/ca.serial
new_certs_dir = $base_dir
# 修正CRL路径为完整相对路径
crl = $base_dir/crl/crl.pem
crl_dir = $base_dir/crl
# 指定CRL编号文件路径
crlnumber = $base_dir/crl/number
# 设置CRL默认有效期
default_crl_days = 30
default_md = sha256
default_days = 365
email_in_dn = no
policy = server_policy
copy_extensions = copy
uniqueSubject = no
# 指定CRL使用的扩展段
crl_extensions = crl_ext

# 在ca.conf末尾添加CRL扩展段
[ crl_ext ]
authorityKeyIdentifier=keyid:always,issuer:always

2. 吊销证书时使用错误的证书文件

脚本中使用client.pem执行吊销,但该文件是从PKCS12导出的复合文件,OpenSSL的ca -revoke命令需要使用CA签署的原始客户端证书(client.crt)。修改脚本的吊销部分:

# revoke
CRT_FILE=$CRT_DIR/client.crt  # 替换为原始签署证书
openssl ca -config "$CA_DIR/ca.conf" -cert "$CA_DIR/ca.crt" -keyfile "$CA_DIR/ca.key" -revoke "$CRT_FILE"
# 直接覆盖原CRL文件,无需生成独立的revoked.crl
openssl ca -config "$CA_DIR/ca.conf" -cert "$CA_DIR/ca.crt" -keyfile "$CA_DIR/ca.key" -gencrl -out "$CA_DIR/crl/crl.pem"

3. 分离的CRL配置导致数据不共享

原流程使用独立的crl.conf生成初始CRL,但该配置使用单独的index.txt数据库,与CA的吊销记录数据库(ca.index)不共享,导致无法读取吊销信息。删除单独的crl.conf,统一使用ca.conf生成CRL,初始CRL生成命令改为:

# 初始CRL生成,使用ca.conf而非独立的crl.conf
openssl ca -gencrl -keyfile "$CA_DIR/ca.key" -cert "$CA_DIR/ca.crt" -out "$CRL_DIR/crl.pem" -config "$CA_DIR/ca.conf"

4. 移除冗余的CRL数据库文件

由于统一使用CA的ca.index作为吊销记录,无需单独的crl/index.txt,脚本中可删除以下冗余代码:

# 移除该行
touch "$CRL_DIR/index.txt"
# 保留number文件创建即可
echo 00 > "$CRL_DIR/number"

验证修复结果

执行修改后的脚本后,运行以下命令查看CRL内容:

openssl crl -in client/svc/ca/crl/crl.pem -text -noout

应能看到包含被吊销证书的记录,且无报错信息。

内容的提问来源于stack exchange,提问作者GlinesMome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 05:15:02