我正在建立一个拥有以下组件的自己的证书链:
Root Certificate - Intermediate Certificate - User Certificate
Root Cert是自签名证书,中级证书由Root和User by Intermediate签名。
现在我想验证用户证书是否有根证书的锚点。
用
openssl verify -verbose -CAfile RootCert.pem Intermediate.pem
验证没问题。在下一步中,我使用
验证用户证书
openssl verify -verbose -CAfile Intermediate.pem UserCert.pem
并且验证在0深度查找时显示错误20:无法获得本地颁发者证书
有什么问题?
答案 0 :(得分:117)
来自'verify'文档:“如果找到的证书是其自己的颁发者,则认为它是根CA”。换句话说,根CA需要自签名才能进行验证。这就是你的第二个命令不起作用的原因。
请改为尝试:
openssl verify -CAfile RootCert.pem -untrusted Intermediate.pem UserCert.pem
它将在一个命令中验证您的整个链。
答案 1 :(得分:39)
这是cat
为数不多的合法工作之一:
openssl verify -verbose -CAfile <(cat Intermediate.pem RootCert.pem) UserCert.pem
更新
正如Greg Smethells在评论中指出的那样,这个命令隐含地信任Intermediate.pem 。我建议阅读the post Greg references的第一部分(第二部分是关于pyOpenSSL的,与此问题无关)。
如果帖子消失,我会引用重要段落:
不幸的是,“中间”证书实际上是root / self-signed 使用建议的命令时,将被视为受信任的CA 以上:
$ openssl verify -CAfile&lt;(cat geotrust_global_ca.pem rogue_ca.pem) fake_sometechcompany_from_rogue_ca.com.pem fake_sometechcompany_from_rogue_ca.com.pem:好的
似乎openssl将在遇到根证书时立即停止验证链,如果它是自签名的,也可能是Intermediate.pem。在这种情况下,不考虑RootCert.pem。因此,在依赖上述命令之前,请确保Intermediate.pem来自受信任的来源。
答案 2 :(得分:12)
问题是,openssl -verify
没有完成这项工作。
As Priyadi mentioned,openssl -verify
在第一个自签名证书处停止,因此您并未真正验证链,因为中间证书通常是自签名的。
我认为您希望101%确定,在尝试将其安装到高效的Web服务中之前,证书文件是正确的。这个配方在这里执行这个飞行前检查。
请注意the answer of Peter is correct,但是openssl -verify
的输出并不是所有真正后续工作的线索。是的,它可能会发现一些问题,但并非全部。
这是一个脚本,用于在将证书链安装到Apache之前验证证书链。也许这可以通过一些更神秘的OpenSSL魔法来增强,但我不是OpenSSL大师和以下作品:
#!/bin/bash
# This Works is placed under the terms of the Copyright Less License,
# see file COPYRIGHT.CLL. USE AT OWN RISK, ABSOLUTELY NO WARRANTY.
#
# COPYRIGHT.CLL can be found at http://permalink.de/tino/cll
# (CLL is CC0 as long as not covered by any Copyright)
OOPS() { echo "OOPS: $*" >&2; exit 23; }
PID=
kick() { [ -n "$PID" ] && kill "$PID" && sleep .2; PID=; }
trap 'kick' 0
serve()
{
kick
PID=
openssl s_server -key "$KEY" -cert "$CRT" "$@" -www &
PID=$!
sleep .5 # give it time to startup
}
check()
{
while read -r line
do
case "$line" in
'Verify return code: 0 (ok)') return 0;;
'Verify return code: '*) return 1;;
# *) echo "::: $line :::";;
esac
done < <(echo | openssl s_client -verify 8 -CApath /etc/ssl/certs/)
OOPS "Something failed, verification output not found!"
return 2
}
ARG="${1%.}"
KEY="$ARG.key"
CRT="$ARG.crt"
BND="$ARG.bundle"
for a in "$KEY" "$CRT" "$BND"
do
[ -s "$a" ] || OOPS "missing $a"
done
serve
check && echo "!!! =========> CA-Bundle is not needed! <========"
echo
serve -CAfile "$BND"
check
ret=$?
kick
echo
case $ret in
0) echo "EVERYTHING OK"
echo "SSLCertificateKeyFile $KEY"
echo "SSLCertificateFile $CRT"
echo "SSLCACertificateFile $BND"
;;
*) echo "!!! =========> something is wrong, verification failed! <======== ($ret)";;
esac
exit $ret
请注意,
EVERYTHING OK
之后的输出是Apache设置,因为使用NginX
或haproxy
的人通常也可以完美地阅读和理解这一点;)
有一个GitHub Gist可能会有一些更新
此脚本的先决条件:
/etc/ssl/certs
中拥有受信任的CA根数据,例如在Ubuntu上DIR
:
DIR/certificate.crt
包含证书DIR/certificate.key
,其中包含您的网络服务的密钥(不含密码)DIR/certificate.bundle
,其中包含CA-Bundle。关于如何准备捆绑包,请参阅下文。./check DIR/certificate
(这假定脚本在当前目录中名为check
)CA-Bundle is not needed
的可能性非常小。这意味着,您(阅读:/etc/ssl/certs/
)已经信任签名证书。但这在WWW中是不太可能的。 如何创建certificate.bundle
文件?
在WWW中,信任链通常如下所示:
/etc/ssl/certs
的可信证书certificate.crt
)现在,评估从下到上进行,这意味着,首先,您的证书被读取,然后需要未知的中间证书,然后可能会签署交叉签名证书,然后查询/etc/ssl/certs
找到合适的可信证书。
ca-bundle必须以正确的处理顺序组成,这意味着,第一个需要的证书(签署证书的中间证书)首先出现在捆绑中。然后需要交叉签名证书。
通常,您的CA(签署证书的机构)将提供此类正确的ca-bundle文件。如果没有,您需要选择所有需要的中间证书并将它们cat
一起放入一个文件中(在Unix上)。在Windows上,您只需打开一个文本编辑器(如notepad.exe
)并将证书粘贴到文件中,第一个需要在顶部,然后跟随其他文件。
还有另外一件事。文件需要采用PEM格式。一些CA发布DER(二进制)格式。 PEM很容易发现:它是ASCII可读的。有关如何将某些内容转换为PEM的信息,请参阅How to convert .crt to .pem并按照黄砖路行驶。
示例:
你有:
intermediate2.crt
签署了您的certificate.crt
intermediate1.crt
另一个中间证书,其中包含intermediate2.crt
crossigned.crt
这是来自另一个CA的交叉签名证书,签名为intermediate1.crt
crossintermediate.crt
这是签署crossigned.crt
的其他CA的另一个中间人(您可能永远不会看到这样的事情)然后正确的cat
将如下所示:
cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle
你怎么能找出需要的文件和顺序?
好吧,试验,直到check
告诉你一切正常。它就像一个解决谜语的电脑益智游戏。每一个。单。时间。即使是专业人士。但是每次你需要这样做时你会变得更好。所以你绝对不会因为那种痛苦而独自一人。它是SSL,你是&#39;知道? SSL可能是我在30多年的专业系统管理中见过的最糟糕的设计之一。有没有想过为什么加密在过去30年里还没有成为主流?这就是原因。 &#39;努夫说。
答案 3 :(得分:5)
我必须对letsencrypt证书进行验证,我这样做了:
openssl verify -CAfile letsencrypt-root-cert/isrgrootx1.pem.txt -untrusted letsencrypt-intermediate-cert/letsencryptauthorityx3.pem.txt /etc/letsencrypt/live/sitename.tld/cert.pem
/etc/letsencrypt/live/sitename.tld/cert.pem: OK
希望它可以帮助您获得letsencrypt证书。 感谢Priyadi,您的解决方案帮助我找到了这个命令。 Palease确保提出他的解决方案。
答案 4 :(得分:3)
在完全相同的问题上打了一整天之后,在没有SSL证书的先验知识的情况下,我下载了CERTivity Keystores Manager并将我的密钥库导入其中,并获得了明确的证书链可视化。< / p>
屏幕截图:
答案 5 :(得分:3)
如果您只想验证UserCert.pem
的发布者实际上 Intermediate.pem
,请执行以下操作(示例使用:OpenSSL 1.1.1
):
openssl verify -no-CAfile -no-CApath -partial_chain -trusted Intermediate.pem UserCert.pem
您将获得:
UserCert.pem: OK
或
UserCert.pem: verification failed
答案 6 :(得分:0)
openssl verify
不像 SSL 客户端那样处理证书链。您可以通过三步流程复制他们所做的事情:
(cat cert.pem chain.pem | diff -q fullchain.pem -) && \
openssl verify chain.pem && \
openssl verify -CAfile chain.pem cert.pem
这将确认 fullchain.pem
== cert.pem
+ chain.pem
并且根据您系统上安装的 CA(通常在 /etc/ssl/certs
中),它是合法的1}} 包)。
如果您尝试验证letsencrypt/ACME,请注意letsencrypt为每个域提供四个文件:
ca-certificates
cert.pem
chain.pem
fullchain.pem
其中,您的证书对是 (privkey.pem
, fullchain.pem
), not (privkey.pem
, cert.pem
) 或 ({{1 }}, privkey.pem
).
例如,在 nginx.conf 中,您将输入:
chain.pem
答案 7 :(得分:-5)
您可以使用openssl轻松验证证书链。 fullchain将包含CA证书,因此您应该看到有关CA和证书本身的详细信息。
openssl x509 -in fullchain.pem -text -noout