【发布时间】:2019-03-14 17:06:43
【问题描述】:
我目前正在使用证书的网站上测试 API,方法是在本地 Windows 机器上的命令行中执行使用 curl 的 php 脚本。但是脚本永远无法到达服务器。我已经为这个明显频繁的错误查找了解决方案,并尝试了以下方法,但没有成功:
- 确保证书仍然有效。
- 确保在 php.ini 中启用了 openssl php 扩展,并且 .dll 确实存在。
- 从https://curl.haxx.se/docs/caextract.html 下载最新的证书包,如this question 的回答中所述,并将其添加到 php.ini。我还检查了我尝试联系的网站的证书颁发机构确实在该捆绑包中(在我的例子中是 Comodo)。
- 下载了一个较旧的证书包,该包更接近网站证书有效期的开始时间。
- 通过this link直接从证书颁发机构下载证书,并将.crt添加到我的php.ini文件中。
- 使用this tool 将上面检索到的 .crt 文件转换为 .pem,然后将其添加到 php.ini(替换上面的那个)。
这是我用于测试的脚本(我只在命令行中使用 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);
如果我取消注释其中的两行以完全绕过证书验证,它会完美运行,但我想避免这种情况。
在所有情况下,我都尝试了带有斜杠和反斜杠的路径,我确定使用了正确的 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
我目前不知道检查我做错了什么以及如何解决它。
【问题讨论】:
-
“无法获取颁发者证书”始终意味着您从远程端收到一个证书,在本地您无法找到对其进行签名的证书。您首先需要确切了解您获得的证书以及颁发者。然后,您需要确保在您的相关信任库中添加此颁发者证书。
-
真正困难的部分是要知道应该如何实际检索 curl 所需的证书。我现在要感谢 Firefox 提供了执行此操作的工具。
-
2020 年更新:firefox 不再能够提供我需要的功能,请参阅下面的答案以获得更稳定的方法。