我们有超过 700 个证书,由 Easy-RSA 2 为 OpenVPN 使用生成。我不知道这是怎么发生的(怀疑有人删除了一次index.txt
,serial
或两者都删除了),但是生成的证书中有一半以上具有相同的序列号。此外,原始index.txt
证书仅包含所有证书的一半(后一半),不包括以前的证书。
所以,新的证书可以做,没关系。但是,当我尝试撤销不在 中的证书时index.txt
,出现错误。
我尝试index.txt
通过脚本重新创建:
for cert in *.crt
do
echo "-> $cert"
enddate=`openssl x509 -enddate -noout -in $cert | sed 's/notAfter=//' | awk '\
{ year=$4-2000;
months="JanFebMarAprMayJunJulAugSepOctNovDec" ;
month=1+index(months, $1)/3 ;
day=$2;
hour=substr($3,1,2) ;
minutes=substr($3,4,2);
seconds=substr($3,7,2);
printf "%02d%02d%02d%02d%02d%02dZ", year, month, day, hour, minutes, seconds}'`
serial=`openssl x509 -serial -noout -in $cert |sed 's/serial=//'`
subject=`openssl x509 -subject -noout -in $cert |sed 's/subject= //'`
echo -e "V\t$enddate\t\t$serial\tunknown\t$subject" >>index.txt
done
Run Code Online (Sandbox Code Playgroud)
它一一读取证书,获取它们的数据并填充新的index.txt
. 一切似乎都很好。
但是,根据上面的文本,脚本通过具有相同序列号的证书填充它。因此,有了这个新创建的index.txt
证书,我无法对证书进行任何操作(创建、撤销等...)
问题是:index.txt
如果我拥有所有证书,是否有可能修复底座?或者,也许,以某种方式更改证书的序列号(简单的更改*.crt
文件头什么也不做 - 查询时序列号保持旧openssl
)
如果没有-我只需要吊销证书,which're不在index.txt
,我可以做到这一点,而不index.txt
基地?
小智 2
我们有超过 700 个证书...生成的证书中有一半以上具有相同的序列号...原始 index.txt 仅包含所有证书的一半(后一半),不包括以前的证书。
我将尽力为您指明正确的方向,但我可能无法将其完成,因为我没有设置测试装置并重复问题。我提前道歉。
如果您想要在私有 PKI 中颁发证书的更高级别概述,请参阅如何使用证书颁发机构签署证书签名请求?它解释了如果 Easy-RSA 没有为您执行操作,您将如何手动执行操作。
另一个重要文档是RFC 4158,Internet X.509 公钥基础设施:认证路径构建。这是__the__文档,它解释了什么是匹配,以及如何使用像{Issuer Distinguished Name,Serial Number}
或 这样的元组{Subject Distinguished Name,Public Key Identifier}
来比较两个证书的等效性。OpenSSL 使用此文档进行匹配。另请参阅第 3.5.15 节“端点可分辨名称 (DN) 匹配”和第 3.5.12 节“匹配密钥标识符 (KID)”。
序列号应该是唯一的。这是需要克服的问题。主题专有名称 (DN)则是另一回事。如果你openssl.cnf
有unique_subject=yes
,那么它们就不能重复。如果unique_subject=no
,则 DN 可以重复。
我认为你需要做一些事情。首先,使用 OpenSSL 实用程序的现代或更新版本。这里,“现代”是指较晚的 1.0.2 或 1.1.0 之一。该实用程序的早期版本在匹配名称和序列号方面存在微妙的问题。
其次,检查您的配置文件(通常openssl.cnf
但您可以使用不同的,可能是复制的文件-config filename
)并记下相关设置,例如serial.txt
和unique_subject=no
。[CA_Default]
我相信这些是来自以下的相关内容openssl.cnf
:
base_dir = .
certificate = $base_dir/cacert.pem # The CA certifcate
private_key = $base_dir/cakey.pem # The CA private key
new_certs_dir = $base_dir # Location for new certs after signing
database = $base_dir/index.txt # Database index file
serial = $base_dir/serial.txt # The current serial number
unique_subject = no # Allow reuse of subjects
Run Code Online (Sandbox Code Playgroud)
第三,备份所有内容,尤其是重要的内容,例如index.txt
和serial.txt
。
第四,创建要撤销的证书列表。该列表可能包含诸如文件名 - 之类的条目john-doe-vpn.pem
。如果您愿意,请将它们移动到自己的文件夹中。最好每个都应该有一个唯一的序列号,并且它们必须具有相同的发行者名称;尽管 OCSP 协议可以,但和openssl ca
函数ocsp
不能同时处理多个发行者。
第五,index.txt
为每个序列创建一个包含一行的新内容。一种方法是从每个证书文件中提取主题、序列号和过期时间,如您发布的脚本中所示,尽管您可以将大部分 shell 工作折叠到每个证书一个 openssl 和一个 awk 中:
for f in *files*; do
openssl x509 -noout -enddate -serial -subject -in $f \
| awk 'BEGIN{FS="=";OFS="\t"} /^serial/{num=$2} /^subject/{sub=$2}
/^notAfter/{split($2,a,/ /);mon=index(months,a[1])/3+1;day=a[2]...exp=sprintf(...)}
END{print "V",exp,"",num,sub}' >>index.txt
done
Run Code Online (Sandbox Code Playgroud)
如果很难(可靠地)提前删除重复的连续剧,您可以将所有内容放入其中,然后使用awk -F'\t' '!already[$4]++'
或sort -t$'\t' -k4,4 -u
或类似的命令丢弃重复的内容。
openssl ca [-config conffile] -valid certfile
1.0.2 及更高版本中提供的另一种方法是使用自动执行此提取,但仅在 1.1.0 中记录。但-valid
每次都不必要地加载 CA 私钥,因此,如果您的私钥是密码加密的(这是一种很好的做法),这将意味着一遍又一遍地输入您的密码;为了节省时间,请暂时用临时未加密密钥和匹配但伪造(可能是自签名)的证书替换真正的 CA 密钥和证书。-valid
不会写入重复的序列条目,因此您不必担心排除或删除它们。
在文件中放入serial
一个值,该值至少是任何先前颁发的证书的最高值;如果您想跳到下一个10000
或1000000
其他任何地方以确保安全并且可能也更清楚,那很好。unique_subject=no
此时您可能需要进行设置。
第六,将index
文件中的每个证书(序列号)标记为已撤销。您可以循环使用每个证书文件openssl ca -revoke
,但使用 awk 更容易,例如:
awk -F'\t' -vOFS='\t' '{$1="R"; $3="161101000000Z"}' <index.txt >temp && mv temp index.txt
# if you want, you can add a comma and a reason, see man ca or
# online at https://www.openssl.org/docs/manmaster/man1/ca.html
# under -crl_reason. But there isn't a code for 'CA stupid', and
# in practice the reason doesn't really matter to reliers except
# you should't use hold or remove (latter noted in the man)
Run Code Online (Sandbox Code Playgroud)
第七,如果(任何)旧证书指定了 OCSP 扩展,则使用它生成 CRLindex
和/或使用它设置 OCSP 响应程序。openssl ca -gencrl [-crldays n] [-out file]
第八,一旦您分发 CRL 和/或开始运行(新的)OCSP 响应程序,所有具有受影响序列的证书都将被撤销,并且如果使用(并正确检查),将导致通信失败。如果您的系统仍在使用的证书中存在任何重复的序列号,则必须首先替换它们。如果您仍然拥有来自使用受影响证书的系统的请求文件 (CSR),您只需重新颁发openssl ca [-config conffile] [-in reqfile | -infiles reqfile...]
新证书并将其发送到主题系统,然后让这些系统的操作员安装它们。否则,您需要首先让每个系统的运营商向您发送一份 CSR,该 CSR 可以是他们之前使用(并保存)的 CSR,也可以是他们生成的新 CSR。
最后,从旧文件中恢复所有“良好”条目(您未撤销的连续出版物)index
,并与上面#8 中颁发的替换证书的任何新条目相结合。如果您正在运行 OCSP 响应程序(见上文),您还必须保留已撤销的条目;不是没关系,但可能更容易。如果旧值低于最高的旧证书或最高的新替换证书,则不要恢复旧值,而是让它继续从新值递增。serial
关于日期for-loop
和印刷日期:
hour=substr($3,1,2) ;
minutes=substr($3,4,2);
seconds=substr($3,7,2);
printf "%02d%02d%02d%02d%02d%02dZ", year, month, day, hour, minutes, seconds}'`
Run Code Online (Sandbox Code Playgroud)
甚至不用担心日期。如果它们已过期,并且您的 PKI 运行正常,则无法使用它们。如果这让您感觉更好,那么删除与证书和公钥关联的私钥。
您所关心的只是要撤销的证书列表及其序列号和可分辨名称。在这里,您的列表将由以下证书组成:(1) 持有未过期证书和私钥的现有员工(即员工即将退休或终止合同);(2) 员工丢失设备(即私钥丢失);ETC。
您还有另一个选择...将现有的 PKI 彻底销毁并重新开始。在这种情况下,步骤 (1) 是撤销根 CA 和所有中间/从属 CA。然后,扔掉私钥。步骤 (2) 是创建新的根 CA,颁发新的中间/从属 CA,最后颁发新的最终实体证书。对于步骤(2),您甚至可以跳签名派对舞蹈。
不管你相信与否,OpenStack 使用了这种策略(或者正在考虑使用它)。它是一种“临时 PKI”,旨在保留足够长的时间来满足您的需求;然后当出现问题时被丢弃。
为了一笑,您可能想看看 Peter Gutmann 的工程安全。当涉及到 PKI 和公共 CA 时,他是无情的。