据我了解,任何使用X.509证书的软件都可以自行决定证书是否可信。
AFAIK OpenSSL只是查询一个列表(例如/ etc / ssl / certs)并检查证书是否存在。
OpenSSL是否有办法列出它信任的所有证书?我知道我可以自己查询该文件(在我特定的OpenSSL安装上),但是有一种(与安装无关的)方法从OpenSSL本身获取可信列表吗?
答案 0 :(得分:16)
AFAIK OpenSSL只是查询一个列表(例如/ etc / ssl / certs)并检查证书是否存在。
不,默认情况下,OpenSSL不信任任何内容。你必须指导它信任什么。甚至有一个FAQ主题涵盖它:Why does <SSL program>
fail with a certificate verify error?:
此问题通常由日志消息说明 像“无法获得本地发行人证书”或“自签名 证书“。证书验证时,其根CA必须是 OpenSSL“信任”这通常意味着CA证书必须 放在目录或文件中并配置相关程序 阅读它。 OpenSSL程序'verify'的行为方式与此类似 发出类似的错误消息:检查verify(1)程序手册页 了解更多信息。
您还可以测试与Google的连接,了解OpenSSL的行为方式:
$ openssl s_client -connect google.com:443
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
...
Start Time: 1407377002
Timeout : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)
请注意,上述操作失败,因为OpenSSL默认情况下不信任 GeoTrust Global CA 。实际上,链中还有另一个信任点,那就是 Google Internet Authority G2 。
您可以通过告诉OpenSSL要信任什么来解决问题。下面,我使用-CAfile
选项与Google Internet Authority G2:
$ openssl s_client -connect google.com:443 -CAfile google-ca.pem
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com
verify return:1
...
Start Time: 1407377196
Timeout : 300 (sec)
Verify return code: 0 (ok)
接下来,您可以通过转到cURL和download cacert.pem
来充当浏览器。 cacert.pem
中包含大量CA:
$ openssl s_client -connect google.com:443 -CAfile cacert.pem
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com
verify return:1
...
Start Time: 1407377356
Timeout : 300 (sec)
Verify return code: 0 (ok)
你不像拥有数百个CA和下属CA的浏览器那么糟糕,但是你已经接近了:
$ cat cacert.pem | grep -o "\-\-\-\-\-BEGIN" | wc -l
153
OpenSSL安全模型与Web应用程序/浏览器安全模型形成对比,其中浏览器携带称为证书颁发机构(CA)的信任锚或信任点列表。 注意:在此模型中,错误的CA可能声称要对网站进行认证,而浏览器则不会更明智。
过去曾发生这种情况,将来可能再次发生。有关PKIX搞笑业务的良好历史,请参阅CAcert's Risk History。例如,您知道 Google Internet Authority G2 和 GeoTrust Global CA 认证Google的网站。 Dutch CA called Diginotar没有理由要求对其进行认证,或French Cyberdefense Agency声称对其进行认证。
与安全模型相关:Web应用程序/浏览器模型的另一个问题是您无法打包您的应用程序所需的一个信任锚或CA并使用它(假设您有一个受信任的分发渠道) 。您的证书会随CA Zoo一起被扔进去。其他人仍然可以声称对您的网站进行认证,并且您可以声称对其他网站进行认证。
安全模型Web应用程序降级为低价值数据的原因之一。 Web应用程序不应处理中等价值或高价值数据,因为我们无法放置所需的安全控制。
OpenSSL是否有办法列出它信任的所有证书?
不需要,因为该列表有0个成员:)
另见How to find out the path for openssl trusted certificate?。
答案 1 :(得分:5)
我最近调查了这一点,发现无法让OpenSSL列出其受信任集中的证书。我发现,最好的方法是“自己查阅文件[/ etc / ssl / certs](在我特定的OpenSSL安装上)”。
您可以更加独立于安装,找到OpenSSL参考的目录。 openssl version -d
打印到它的路径。
% openssl version -d
OPENSSLDIR: "/opt/local/etc/openssl"
OpenSSL在这里查找名为cert.pem
的文件和子目录certs/
。它找到的证书被openssl s_client
和openssl verify
视为受信任(来源:文章, What certificate authorities does OpenSSL recognize? )。
所以,你可以这样做:
% find -H `openssl version -d | sed -E 's/OPENSSLDIR: "([^"]*)"/\1/'`/(cert.pem|certs) \
-type f -exec cat {} \+
这将打印出OpenSSL期望包含证书的文件的全部内容。如果您希望少于整个文件,请使用适当的命令替换cat
。
答案 2 :(得分:2)
我很想知道自从jww的回应以来,这是否有所改变。
如果我提交: $ openssl s_client -connect google.com:443
它成功运行,检索4个总证书,然后返回:
Start Time: 1484661709
Timeout : 300 (sec)
Verify return code: 0 (ok)
我认为这是因为服务器应该设置为与证书一起发送验证完整链所需的任何中间证书和根证书,对吗?
答案 3 :(得分:0)
自我解答:此text建议调用SSL_CTX_set_default_verify_paths()
以信任与系统有关的目录中的证书。