我正在使用XAMPP进行开发。最近我将xampp的安装从旧版本升级到1.7.3。
现在当我卷曲启用HTTPS的网站时,我得到以下异常
致命错误:未捕获的异常'RequestCore_Exception',消息'cURL resource:Resource id#55; cURL错误:SSL证书问题,验证CA证书是否正常。详细信息:错误:14090086:SSL例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败(60)'
每个人都建议使用PHP代码中的一些特定curl选项来解决这个问题。我认为这不应该是这样的。因为我的旧版XAMPP没有任何问题,只是在安装新版本后才发生。
我需要帮助来弄清楚我的PHP安装中哪些设置发生了变化,Apache等可以解决这个问题。
curl曾经包含一个已接受的CA列表,但不再捆绑任何CA证书。因此,默认情况下,它会拒绝所有SSL证书作为无法验证的。
你必须得到你的CA的证书和点卷曲。更多细节在cURLS的Details on Server SSL Certificates。
当我试图从www.googleapis.com获取GuzzleHttp(Mac +上的php + apache)时,我最终到了这里。
这是我的最终解决方案,以防万一。
查看证书链中的任何域名都会给您出现此错误。对我来说这是googleapis.com
openssl s_client -host www.googleapis.com -port 443
你会得到这样的东西:
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.googleapis.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
注意:我在修复问题后捕获了这个,你的链输出可能看起来不同。
然后你需要查看php中允许的证书。在页面中运行phpinfo()。
<?php echo phpinfo();
然后查找从页面输出加载的证书文件:
openssl.cafile /usr/local/php5/ssl/certs/cacert.pem
这是您需要通过向其添加正确的证书来修复的文件。
sudo nano /usr/local/php5/ssl/certs/cacert.pem
您基本上需要将正确的证书“签名”附加到此文件的末尾。
您可以在此处找到其中一些内容:如果需要,您可能需要谷歌/搜索链中的其他人。
它们看起来像这样:
(注意:这是一个图像,所以人们不会简单地从stackoverflow复制/粘贴证书)
一旦正确的证书在此文件中,请重新启动apache并进行测试。
您可以尝试重新安装ca-certificates
软件包,或明确允许有问题的证书,如here所述。
解决方案非常简单!把这行放在curl_exec
之前:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
对我来说它有效。
这是Windows中一个非常常见的问题。你只需要将cacert.pem
设置为curl.cainfo
。
从PHP 5.3.7开始,您可以:
php.ini
- 添加curl.cainfo =“PATH_TO / cacert.pem”否则,您需要为每个cURL资源执行以下操作:
curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");
警告:这可能会引入SSL旨在防范的安全问题,从而导致整个代码库不安全。这违背了所有推荐的做法。
但是一个非常简单的解决方案对我来说是:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
在致电之前:
curl_exec():
在php文件中。
我相信这会禁用SSL证书的所有验证。
资料来源:http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html
Curl: SSL certificate problem, verify that the CA cert is OK
07 April 2006
使用Curl打开安全URL时,您可能会收到以下错误:
SSL证书问题,验证CA证书是否正常
我将解释为什么错误以及你应该怎么做。
摆脱错误的最简单方法是在脚本中添加以下两行。该解决方案存在安全风险。
//WARNING: this would prevent curl from detecting a 'man in the middle' attack curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
让我们看看这两个参数是做什么的。引用手册。
CURLOPT_SSL_VERIFYHOST:1检查SSL对等证书中是否存在公用名。 2检查是否存在公用名,并验证它是否与提供的主机名匹配。
CURLOPT_SSL_VERIFYPEER:FALSE停止CURL验证对等方的证书。可以使用CURLOPT_CAINFO选项指定要验证的备用证书,也可以使用CURLOPT_CAPATH选项指定证书目录。如果禁用CURLOPT_SSL_VERIFYPEER,则CURLOPT_SSL_VERIFYHOST也可能需要为TRUE或FALSE(默认为2)。将CURLOPT_SSL_VERIFYHOST设置为2(这是默认值)将保证提供给您的证书具有与您用于访问远程资源的URN匹配的“公用名”。这是一个健康的检查,但它不能保证您的程序没有被解除。
Enter the 'man in the middle'
您的程序可能会误导与另一台服务器通话。这可以通过几种机制来实现,比如dns或arp中毒(这是另一天的故事)。入侵者还可以使用您的程序所期望的相同“通用名称”对证书进行自签名。通信仍然会被加密,但你会把你的秘密泄露给冒名顶替者。这种攻击被称为“中间人”
Defeating the 'man in the middle'
好吧,我们需要验证提交给我们的证书是否真实。我们通过将它与我们合理*信任的证书进行比较来做到这一点。
如果远程资源受到Verisign,GeoTrust等主要CA之一颁发的证书的保护,您可以安全地与Mozilla的CA证书包进行比较,您可以从http://curl.haxx.se/docs/caextract.html获得该证书包。
将文件
cacert.pem
保存在服务器中的某个位置,并在脚本中设置以下选项。curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, TRUE); curl_setopt ($ch, CURLOPT_CAINFO, "pathto/cacert.pem");
以上所有信息转到:http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html
上面的解决方案很棒,但是如果你使用的是WampServer,你可能会发现在curl.cainfo
中设置php.ini
变量不起作用。
我最终发现WampServer有两个php.ini
文件:
C:\wamp\bin\apache\Apachex.x.x\bin
C:\wamp\bin\php\phpx.x.xx
第一个显然用于通过Web浏览器调用PHP文件,而第二个用于通过命令行或shell_exec()
调用命令时。
TL; DR
如果使用WampServer,则必须将curl.cainfo
行添加到两个php.ini
文件中。
为了所有圣洁的爱...
在我的例子中,我必须将openssl.cafile
PHP配置变量设置为PEM文件路径。
我相信很多系统都在PHP的配置中设置curl.cainfo
正是我所需要的,但在我正在使用的环境中,这是使用Debian 8(jessie)和PHP 5.6的eboraas/laravel docker容器。 ,设置该变量没有做到这一点。
我注意到php -i
的输出没有提到关于特定配置设置的任何内容,但它确实有几行关于openssl
。有一个openssl.capath
和openssl.cafile
选项,但只是设置第二个允许curl通过PHP最终可以使用HTTPS URL。
有时,如果您尝试联系的应用程序具有自签名证书,则http://curl.haxx.se/ca/cacert.pem的常规cacert.pem无法解决问题。
如果您确定服务端点URL,请通过浏览器点击它,手动将证书保存在“带链(XEM)的X 509证书”格式中。将此证书文件指向
curl_setopt ($ch, CURLOPT_CAINFO, "pathto/{downloaded certificate chain file}");
我在亚马逊AMI linux上有同样的错误。
我通过在/etc/php.d/curl.ini上设置curl.cainfo来解决
https://gist.github.com/reinaldomendes/97fb2ce8a606ec813c4b
2018年10月增加
在Amazon Linux v1上编辑此文件
vi /etc/php.d/20-curl.ini
添加此行
curl.cainfo="/etc/ssl/certs/ca-bundle.crt"
设置CURLOPT_CAINFO的curl选项时请记住使用单引号,使用双引号只会导致另一个错误。所以你的选择应该是这样的:
curl_setopt ($ch, CURLOPT_CAINFO, 'c:\wamp\www\mywebfolder\cacert.pem');
另外,在你的php.ini文件中,设置应该写成:(注意我的双引号)
curl.cainfo = "C:\wamp\www\mywebfolder"
我把它直接放在说明这一点的行下面:extension=php_curl.dll
(仅限于组织目的,你可以把它放在php.ini
的任何地方,我只是把它放在另一个卷曲参考上,所以当我使用关键词curl搜索时,我可以在一个区域找到两个卷曲引用。)