问题是,这openssl -verify
不能完成任务。
正如Priyadi提到的那样,它会openssl -verify
在第一个自签名证书处停止,因此您实际上并不会验证链,因为中间证书通常是自签名的。
我假设您想101%地确定证书文件是正确的,然后再尝试将其安装在生产性Web服务中。此处的配方完全执行了飞行前检查。
请注意,彼得的回答是正确的,但是输出的结果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可能会有一些更新
此脚本的先决条件:
- 您在其中具有受信任的CA根数据
/etc/ssl/certs
像往常一样在Ubuntu上
- 建立目录
DIR
,在其中存储3个文件:
DIR/certificate.crt
其中包含证书
DIR/certificate.key
其中包含您的Web服务的密钥(无密码)
DIR/certificate.bundle
其中包含CA捆绑包。有关如何准备捆绑包的信息,请参见下文。
- 现在运行脚本:
./check DIR/certificate
这假设脚本已命名check
在当前目录中)
- 脚本输出的可能性极小
CA-Bundle is not needed
。这意味着您(阅读:/etc/ssl/certs/
:)已经信任签名证书。但这在WWW中极不可能。
- 对于此测试,必须在工作站上未使用端口4433。最好只在安全的环境中运行此程序,因为它会很快向公众开放端口4433,这可能会在恶意环境中看到外部连接。
如何创建certificate.bundle
文件?
在WWW中,信任链通常如下所示:
- 来自的受信任证书
/etc/ssl/certs
- 未知的中间证书,可能由另一个CA交叉签名
- 您的证书(
certificate.crt
)
现在,评估从下到上进行,这意味着,首先,读取您的证书,然后需要未知的中间证书,然后可能是交叉签名证书,然后是 /etc/ssl/certs
咨询以找到合适的受信任证书。
ca-bundle必须严格按照正确的处理顺序组成,这意味着,第一个需要的证书(签名您的证书的中间证书)在捆绑包中排在第一位。然后需要交叉签名证书。
通常,您的CA(签署证书的机构)已经提供了适当的ca-bundle文件。如果不是,则需要选择所有需要的中间证书,cat
并将它们一起放入一个文件中(在Unix上)。在Windows上,您可以打开一个文本编辑器(例如notepad.exe
),然后将证书粘贴到文件中,第一个需要放在顶部,其他要紧随其后。
还有另一件事。文件必须为PEM格式。某些CA发行DER(二进制)格式。PEM很容易发现:它是ASCII可读的。有关如何将某些内容转换为PEM的信息,请参阅如何将.crt转换为.pem并遵循黄砖路。
例:
你有:
intermediate2.crt
签署您的中间证书 certificate.crt
intermediate1.crt
另一个中级证书 intermediate2.crt
crossigned.crt
这是来自另一个CA的交叉签名证书 intermediate1.crt
crossintermediate.crt
这是另一个已签名的CA的中间产品crossigned.crt
(您可能永远不会看到这样的东西)
那么适当的cat
将如下所示:
cat intermediate2.crt intermediate1.crt crossigned.crt crossintermediate.crt > certificate.bundle
以及如何找出需要哪些文件以及需要什么顺序?
好吧,进行实验,直到check
告诉您一切都OK 为止。就像解决谜题的电脑益智游戏一样。每一个 单。时间。即使是专业人士。但是,每次需要这样做时,您都会变得更好。因此,您绝对不是唯一一个遭受如此痛苦的人。是SSL,您知道吗?SSL可能是30多年专业系统管理中最糟糕的设计之一。有没有想过为什么加密货币在过去30年没有成为主流?这就是为什么。纳夫说。
man verify
,我发现该-untrusted
参数是指定中间证书时使用的正确参数。