• 作者:老汪软件技巧
  • 发表时间:2024-11-10 11:02
  • 浏览量:

本文正在参加「金石计划」

简介

前面的文章介绍了证书过期,吊销证书以及生成证书吊销列表(CRL)的知识和操作。 当一个证书已经失效后,访问者怎么知道它失效了呢?

显然,浏览器还需要跟 CA 进行某种形式的沟通才能确定当前证书是否已被吊销。主要有下面几种方式:

每种方式各有优缺点,这篇文章介绍如何通过 CRL 列表来验证证书是否失效。

首先,浏览器会在验证证书的时候,可以直接通过检查其过期时间来知道是否失效。 但并没法知道一个还在有效期内的证书是否被吊销。

这时候,它需要根据证书中提供的 CRL 地址去下载一份 CRL 列表,通过检测当前证书是否在 CRL 列表中,来确认当前证书已被吊销,如果确认,就会发出警告或者拒绝建立 HTTPS 连接。

这里有两个要求:

我们知道,当 CA 吊销某个用户证书后,需要手动去更新 CRL 列表(执行 openssl ca -gencrl -out crl/crl.pem)

这个 crl.pem 只是在保存 CA 服务器本地的,浏览器没法访问。因此,CA 服务器需要把它以 HTTP 形式共享出去,这样,网站的访问者才能够下载它,从而能够校验证书是否被吊销。

根据原理,我们可以总结一个大致的流程:

重新生成用户证书(如果之前的证书没有提供 CRL 下载地址的话) 生成用户证书时,必须包含扩展字段(CRL Distribution Points URL),CRL 下载地址就记录在这个扩展字段中CA 生成 CRL 列表(确保正确的 CRL extension)Nginx 提供 CRL 文件共享链接(HTTP 链接)下面介绍详细的操作步骤:1. 配置 [ ca ] 段落,确保包含扩展字段 crlDistributionPoints

只有这样,在使用 openssl ca 命令签发证书时,证书才会带有 CRL 下载地址。

我们使用中间证书签发用户证书,所以这里的配置文件名是f

[ ca ]
default_ca = CA_default
[ CA_default ]
dir               = .
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand
private_key       = $dir/private/ca.key
certificate       = $dir/certs/ca.crt
crl               = $dir/crl/ca.crl
crlnumber         = $dir/crlnumber
crl_extensions    = crl_ext
default_days      = 365
default_crl_days  = 30
default_md        = sha256
preserve          = no
policy            = policy_match
[ policy_match ]
countryName             = optional
stateOrProvinceName     = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
[ v3_ext_echocert ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
crlDistributionPoints = @crl_info
subjectAltName = @alt_names
[ crl_info ]
URI.0 = http://crl.servicelab.com/crl.pem
[alt_names]
IP = 127.0.0.1
DNS = echocert.lab
[ crl_ext ]
authorityKeyIdentifier = keyid:always

注:2. 签发用户证书

重新签发带有 CDP 扩展字段的用户证书(如果之前的证书不包含该字段的话)

openssl ca -days 365 -notext -batch \
    -config ica.cnf \
    -extensions v3_ext_echocert \
    -cert CA/rsa_int_ca.crt \
    -keyfile CA/private/rsa_encrypted.key \
    -passin file:CA/private/password.txt \
    -in ../user_certs/echocert.lab/rsa_echocert.csr \
    -out ../user_certs/echocert.lab/echocert.crt

检查证书

cd user_certs/echocert.lab
openssl x509 -text -noout -in echocert.crt
openssl x509 -text -noout -in echocert.crt | grep -A2 "CRL Distribution Points"

输出样式:

    X509v3 CRL Distribution Points:
        URI:
            http://crl.servicelab.com/crl.pem

3. 生成 CRL

openssl ca -config ica.cnf -passin file:CA/private/password.txt -gencrl -out crl/crl.pem

查看 CRL

openssl crl -noout -text -in crl/crl.pem | grep -B1 "Revocation Date:"

证书解析错误__解析证书失败怎么回事

4. 验证证书是否在 CRL 中

注意,这里我们还需要把 root_ca 与 int_ca 合并起来,否则会提示找不到 int_ca 的 issuer。

cat ../root_ca/CA/rsa_ca.crt CA/rsa_int_ca.crt > ca-chain.crt

openssl verify -crl_check \
    -CAfile ca-chain.crt \
    -CRLfile crl/crl.pem \
    ../user_certs/echocert.lab/echocert.crt

输出结果:

../user_certs/echocert.lab/echocert.crt: OK

5. 撤销证书

现在,我们把 echocert.crt 证书撤销,

openssl ca -config ica.cnf -passin file:CA/private/password.txt -revoke newcerts/08.pem

别忘了更新 CRL

openssl ca -config ica.cnf -passin file:CA/private/password.txt -gencrl -out crl/crl.pem

更新 CRL 的操作是至关重要的,我们可以写个 bash 脚本把这个动作添加到定时任务中:

cat > /usr/local/bin/update-crl.sh << 'EOL'
#!/bin/bash
openssl ca -config ica.cnf -passin file:CA/private/password.txt -gencrl -out /var/www/crl/crl.pem
chmod 644 /var/www/crl/crl.pem
EOL
chmod +x /usr/local/bin/update-crl.sh
(crontab -l 2>/dev/null; echo "0 0 * * * /usr/local/bin/update-crl.sh") | crontab -

检查 index.txt

grep "Echo" index.txt

再次验证证书是否失效

openssl verify -crl_check \
    -CAfile ca-chain.crt \
    -CRLfile crl/crl.pem \
    ../user_certs/echocert.lab/echocert.crt

输出结果:

C=CN, ST=Unknown, O=Echo Certificate, CN=Echo Certificate
error 23 at 0 depth lookup: certificate revoked
error ../user_certs/echocert.lab/echocert.crt: verification failed

总结:

按照上述步骤,我们可以通过 CRL 来验证某用户证书是否被吊销。

接下来,我们用 Nginx 搭建一个 HTTP 服务,提供 CRL 下载链接。

6. Nginx 服务搭建(1) Nginx 配置