我下载了Win32OpenSSL_Light-1_0_2.exe来自 Shining Light Productions并将其安装到默认位置 C:\OpenSSL-Win32
。我复制了文件 ca-bundle.crt到 C:\OpenSSL-Win32\bin
并运行:
C:\OpenSSL-Win32\bin>openssl s_client -connect login.live.com:443 -CAfile ca-bundle.crt
证书链验证失败并显示消息:
Verify return code: 20 (unable to get local issuer certificate)
对相同的 ca-bundle.crt 使用相同的命令使用 OpenSSL 版本 1.0.1e 的 Debian Wheezy 文件返回:
Verify return code: 0 (ok)
如果我将主机名更改为 api.onedrive.com
(相同的命令),我会在 Windows 和 Linux 上得到 Verify return code: 0 (ok)
。
我是做错了什么还是存在已知错误?我怎样才能让它在 Windows 上为 login.live.com
工作?
(最初我在 trying to connect to login.live.com with PHP's cURL extension under Windows XAMPP 时偶然发现了这个问题,但现在它看起来更像是一个 OpenSSL 问题。)
最佳答案
s_client
具有未记录的属性(或者可能是一个长期存在的错误),如果您提供 -CAfile
选项,它不仅会检查给定的 CA 文件但也针对系统默认值(Debian 上的 /usr/lib/ssl/certs
)。如果您使用 strace
运行 openssl s_client
来检查在验证过程中使用了哪些文件,您将看到以下内容:
$ strace -e open openssl s_client -connect login.live.com:443 -CAfile ca-bundle.crt
...
open("ca-bundle.crt", O_RDONLY) = 3
open("/usr/lib/ssl/cert.pem", O_RDONLY) = -1 ENOENT (No such file or directory)
...
open("/usr/lib/ssl/certs/415660c1.0", O_RDONLY) = 4
open("/usr/lib/ssl/certs/415660c1.1", O_RDONLY) = 4
从这个输出中你可以看到它不仅使用给定的 CA 文件进行验证,而且还尝试使用 /usr/lib/ssl/cert.pem
(不存在)然后查看进入 /usr/lib/ssl/certs
以通过主题哈希 415660c1
找到所需的 CA。它最终在 415660c1.1
中找到了它正在寻找的根 CA:
$ openssl x509 -in /usr/lib/ssl/certs/415660c1.1 -text
...
Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
...
Subject: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
由于 Windows 上没有可供 OpenSSL 使用的系统默认值(它不能使用 Windows CA 存储),验证将在那里失败。
至于 api.onedrive.com
:它有另一个信任链,可以使用给定的 CA 包进行完全验证。 strace
的输出显示它不会尝试访问 /usr/lib/ssl/certs
中的任何文件。
关于windows - login.live.com 的 s_client 证书验证在 Windows 中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29111438/