Mic*_*eux 5 php ssl openssl php-curl
我目前正在使用证书的网站上测试 API,方法是在本地 Windows 计算机上的命令行中执行使用curl 的 php 脚本。但该脚本从未成功到达服务器。我已经查找了这个明显频繁的错误的解决方案,并尝试了以下方法,但没有成功:
这是我用于测试的脚本(我仅在命令行中使用 php 执行它):
$data = 'username=myuser&password=mypassword';
$ch = curl_init('https://my.website.com/auth');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_VERBOSE, true);
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_exec($ch);
curl_close($ch);
Run Code Online (Sandbox Code Playgroud)
如果我取消注释其中的两行以完全绕过证书验证,则它可以正常工作,但我想避免这种情况。
在所有情况下,我都尝试了包含斜杠和反斜杠的路径,我确信使用了正确的 php.ini,并且 php 确实可以访问 .pem 文件位置。php 脚本的输出证实了这一点(我已经替换了我正在使用的实际 url):
> * Trying 192.168.200.11...
> * TCP_NODELAY set
> * Connected to my.website.com (192.168.200.11) port 443 (#0)
> * ALPN, offering http/1.1
> * successfully set certificate verify locations:
> CAfile: C:\Development\examples\COMODORSADomainValidationSecureServerCA.pem
> CApath: none
> * NPN, negotiated HTTP1.1
> * SSL certificate problem: unable to get issuer certificate
> * stopped the pause stream!
> * Closing connection 0
Run Code Online (Sandbox Code Playgroud)
我目前没有办法检查我做错了什么以及如何解决它。
所以,最后,这就是我最终设法做到这一点的方法:正如错误所示,并且几个答案也指出,我的配置中缺少证书颁发机构的证书链,并且不在从 https 下载的包中://curl.haxx.se/docs/caextract.html。
事实上,要成功通过 HTTPS 连接到网站,除了您自己网站的证书之外,您还需要与您的证书颁发机构相关的其他证书。导出网站证书并使用专用工具对其进行可视化后,可以在证书路径中检查这一点。Windows 有这样一个工具,默认情况下将与 .cer 文件一起使用 - 而不是文本编辑器。
通常,这些附加证书默认已经存在,但就我而言,它们不是。我的认证路径如下:
Sectigo
|_____Sectigo RSA Domain Validation Secure Server CA
|_____*.example.com
Run Code Online (Sandbox Code Playgroud)
我必须为我的认证路径的 3 个部分中的每一个部分检索一个证书(总共 3 个证书)。
所以最后,我发现这个问题为我指明了正确的方向:我必须以 .cer 格式导出我网站的证书(与 PEM 相同的格式,只是另一个扩展名),在 Windows 中打开我的证书,然后导出分别获得所有3个证书的认证路径。
然后,我将所有 3 个证书复制到从https://curl.haxx.se/docs/caextract.html下载的文件末尾,该文件位于 C:/Development/examples/cacert.pem (您可能想将该文件位于靠近您的 php 安装文件夹的位置)。
然后,我将 php.ini 配置更改为
curl.cainfo=C:/Development/examples/cacert.pem openssl.cafile=C:/Development/examples/cacert.pem
这就成功了!我现在可以毫无问题地连接到该网站。