吊销没有 index.txt 的证书

信息安全 tls 证书吊销 客户
2021-08-23 19:08:28

我为楼梯下托管的一个小型 Apache 服务器生成自签名客户端证书。为了这个目的,下面的脚本被一起破解了——注意它使用'mini-CA' x509 方法,因此在index.txt中没有记录任何内容。

现在我需要撤销一个这样的客户端证书,这需要生成一个 CRL 并将其添加到 Apache。然而,CRL 生成似乎需要一个 index.txt:

root@myserver:~# openssl ca -cert "ssl_ca/ca.crt" -keyfile "ssl_ca/ca.key" -revoke "ssl_badguy/badguy.p12"
./demoCA/index.txt: No such file or directory
unable to open './demoCA/index.txt'

根据证书创建,是否有“独立”CRL 生成命令?我不关心 CA 的持久性或尊重正确的 SSL“理论”(否则一开始就没有自签名)。最初我只是想保护和控制对我的服务器的访问;现在我只想撤销一些访问权限。

当按照./clientcert.sh certname 调用时,以下脚本会创建一个包含所有 bumf(包括 PKCS12)的新目录 /root/ssl_certname/。

#! /bin/bash

echo 'When it asks for a key password (3 times), recommend you use the new key name'
echo 'When it asks for cert details, use "." (blank) for all, EXCEPT CN, which should'
echo 'also be the key name. All other passwords ("Export" etc.) are blank'

clientname="$1"
newdir="/root/ssl_$1"
caloc="/root/ssl_ca"
cert="$newdir/$1"

if [ -d "$newdir" ]; then
    echo "$newdir already exists!"
else
    mkdir "$newdir"
    cd "$caloc"

    openssl genrsa -des3 -out "$cert.key" 2048
    openssl rsa -in "$cert.key" -out "$cert.key.insecure"
    mv "$cert.key" "$cert.key.secure"
    mv "$cert.key.insecure" "$cert.key"

    openssl req -new -key "$cert.key" -out "$cert.csr"

    openssl x509 -req -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -in "$cert.csr" -out "$cert.crt"

    openssl pkcs12 -export -clcerts -in "$cert.crt" -inkey "$cert.key" -out "$cert.p12"
fi

编辑:从技术上讲并不能解决问题,但通过将以下内容添加到我的default-ssl vhost 中,我实现了同样的目标:

# Block badguy client cert
Rewritecond %{SSL:SSL_CLIENT_S_DN_CN} =badguy
RewriteRule (.*) /blocked [QSA,R,L]

- /blocked 实际上不存在的地方(我想我可以在那里放置一个保留页面)。

3个回答

首先,让我们明确一点:客户端证书不是自签名的。它们由 CA 签名,并且该 CA 的证书是自签名的。这很重要,因为自签名证书根本不能被撤销,根据定义:撤销是来自颁发 CA 的信息;自签名证书是它自己的 CA。

第二个重点是 CRL 是迄今为止已撤销证书的列表。因此,如果您撤销一个证书,那么您将拥有一个指定该证书的 CRL;如果您随后撤销另一个证书,那么您的下一个 CRL 必须指定这两个证书。如果下一个 CRL 只讨论第二个证书,那么它会“撤销”第一个证书。对于撤销,Apache 没有内存,或者更确切地说,CRL 是 Apache 的内存。Apache 将使用最新的 CRL 作为所有证书的撤销信息的唯一来源。

这意味着您确实需要在 CA 上维护已撤销证书的列表。openssl命令行工具可以为您维护这样的列表:即文件index.txt,由openssl ca命令行选项维护。如果您不使用它,那么您将不得不自己维护信息,这充其量是很麻烦的。如果您想处理撤销,那么最简单的方法是使用index.txt并让 OpenSSL 管理它。

现在,如果您已经这样做了,那么当然可以使用库以编程方式使用 CA 私钥签署 CRL ;但是没有命令行工具。这在文档中是这样说的:

错误

理想情况下,也应该可以使用适当的选项和文件来创建 CRL。

还有_

限制

文本数据库索引文件是该过程的关键部分,如果损坏,可能难以修复。理论上可以从所有颁发的证书和当前的 CRL 重建索引文件:但是没有选择这样做。

要生成带有一些代码的 CRL,我建议您查看apps/ca.c文件中的 OpenSSL 源代码;搜索“ X509_CRL_new”。这些功能没有得到很好的记录......但是,我坚持认为,如果您开始吊销证书,那么您必须维护一个到目前为止已吊销的所有证书的列表(至少是序列号,最好是每个证书的吊销日期),这基本上意味着制作您自己的等效index.txt文件openssl ca.

现在我发现我必须在另一个层次上添加另一个答案。

您正在尝试使用证书进行授权别。从长远来看,它效果不佳。

证书用于身份验证证书告诉你:这个人拥有那个公钥。撤销是一种取消它的方法,并且是在不再维护密钥所有权时使用的:例如,私钥被盗,因此该人不再“拥有”公钥。在您的情况下,密钥所有权仍然有效:尽管该人被宣布为不受欢迎,但他仍然拥有证书中的公钥。从这个意义上说,撤销不是适当的工具。

从技术上讲,这一切都归结为证书分发成本高昂且证书撤销是异步的事实。做事的“正确”方法是使用证书进行身份验证(客户端证明他的身份),但在其他地方处理授权:授权是您确定允许对给定身份执行哪些操作的过程。试图将授权位推入证书是一条导致悲伤的道路(一个经典的错误,参与 PKI 的每个人在某些时候都会犯这个错误,但仍然是一个错误)。

mod_authz_user模块可以帮助你维护方便文件的授权信息(例如允许或拒绝用户的列表)(我没试过)。

index.txt文件用于跟踪生成的证书和一些属性,如吊销日期。此文件用于生成 CRL。

-gencrl

    this option generates a CRL based on information in the index file.

如果需要,您可以更改文件中的默认文件openssl.conf,或者使用您自己的:https ://stackoverflow.com/a/7770075 ,或者按照下一个答案的建议,尝试使用 x509 命令手动完成工作:https ://stackoverflow.com/a/13047670

后者使用 -CAoptions 来规避openss.conf. 请注意,该index.txt文件是 openssl CA 设置的重要组成部分,不应在生产环境中关闭。