我正在使用XAMPP进行开发。最近,我将xampp的安装从旧版本升级到1.7.3。

现在,当我卷曲启用HTTPS的网站,我得到以下例外

致命错误:未捕获的异常'RequestCore_Exception'与消息 cURL资源:资源 id # 55;cURL错误:SSL证书有问题,请验证CA证书是否OK。细节: SSL例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败(60)'

每个人都建议从PHP代码中使用一些特定的curl选项来解决这个问题。我觉得不应该这样。因为我的旧版本XAMPP没有任何问题,只是在安装新版本后才出现问题。

我需要帮助,以确定在我的PHP安装,Apache等设置更改可以解决这个问题。


curl曾经包含一个接受的证书颁发机构(CA)列表,但从7.18.1及以后不再捆绑任何CA证书。因此默认情况下,它将拒绝所有不可验证的TLS/SSL证书。

您必须获得CA的根证书并将curl指向它。更多详细信息见curl关于TLS/SSL证书验证的详细信息。


警告:这可能会引入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### When opening a secure url with Curl you may get the following error: SSL certificate problem, verify that the CA cert is OK I will explain why the error and what you should do about it. The easiest way of getting rid of the error would be adding the following two lines to your script . This solution poses a security risk tho. //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); Let see what this two parameters do. Quoting the manual. CURLOPT_SSL_VERIFYHOST: 1 to check the existence of a common name in the SSL peer certificate. 2 to check the existence of a common name and also verify that it matches the hostname provided. CURLOPT_SSL_VERIFYPEER: FALSE to stop CURL from verifying the peer's certificate. Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option. CURLOPT_SSL_VERIFYHOST may also need to be TRUE or FALSE if CURLOPT_SSL_VERIFYPEER is disabled (it defaults to 2). Setting CURLOPT_SSL_VERIFYHOST to 2 (This is the default value) will garantee that the certificate being presented to you have a 'common name' matching the URN you are using to access the remote resource. This is a healthy check but it doesn't guarantee your program is not being decieved. ###Enter the 'man in the middle'### Your program could be misleaded into talking to another server instead. This can be achieved through several mechanisms, like dns or arp poisoning ( This is a story for another day). The intruder can also self-sign a certificate with the same 'comon name' your program is expecting. The communication would still be encrypted but you would be giving away your secrets to an impostor. This kind of attack is called 'man in the middle' ###Defeating the 'man in the middle'### Well, we need to to verify the certificate being presented to us is good for real. We do this by comparing it against a certificate we reasonable* trust. If the remote resource is protected by a certificate issued by one of the main CA's like Verisign, GeoTrust et al, you can safely compare against Mozilla's CA certificate bundle which you can get from http://curl.se/docs/caextract.html Save the file cacert.pem somewhere in your server and set the following options in your script. 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


这是Windows系统中很常见的问题。你只需要设置cacert。Pem到卷曲。

从PHP 5.3.7开始,你可以这样做:

下载https://curl.se/ca/cacert.pem并保存到某个地方。 更新php.ini—添加curl。info = "PATH_TO/cacert.pem"

否则,您需要为每个cURL资源执行以下操作:

curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");

有时,如果您试图联系的应用程序具有自签名证书,则正常的cacert。来自http://curl.haxx.se/ca/cacert.pem的Pem不能解决问题。

如果确定服务端点url,通过浏览器点击,手动保存为“X 509链式证书(PEM)”格式。指向该证书文件

curl_setopt ($ch, CURLOPT_CAINFO, "pathto/{downloaded certificate chain file}");   

解决方法很简单!把这一行放在curl_exec之前:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

对我来说很管用。


上面的解决方案很好,但是如果您正在使用WampServer,您可能会发现设置curl。php.ini中的cfo变量不工作。

我最终发现WampServer有两个php.ini文件:

C:\wamp\bin\apache\Apachex.x.x\bin
C:\wamp\bin\php\phpx.x.xx

第一个显然用于通过web浏览器调用PHP文件,而第二个用于通过命令行或shell_exec()调用命令。

博士TL;

如果使用WampServer,则必须添加curl。到两个php.ini文件。


在设置curlopt_caifo的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引用附近,所以当我使用关键字curl搜索时,我可以在一个区域找到两个curl引用。)


我在亚马逊AMI linux上有同样的错误。

我通过设置旋度来解决。/etc/php.d/curl.ini上的info

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"

为了一切神圣的爱…

在我的例子中,我必须设置openssl。cafile PHP配置变量到PEM文件路径。

我相信确实有很多系统可以设置旋度。在PHP的配置中的cayfo正是所需要的,但在我正在使用的环境中,这是eboraas/laravel docker容器,它使用Debian 8 (jessie)和PHP 5.6,设置这个变量并没有做到这一点。

我注意到php -i的输出没有提到任何关于特定配置设置的内容,但它确实有几行关于openssl的内容。有两个openssl。Capath和openssl。cafile选项,但只是设置第二个选项允许curl通过PHP最终可以使用HTTPS url。


当我试图让GuzzleHttp (Mac上的php+apache)从www.googleapis.com获得一个页面时,我结束在这里。

这是我最后的解决方案,希望对大家有所帮助。

查看给您这个错误的域的证书链。对我来说是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

您基本上需要将正确的证书“签名”附加到该文件的末尾。

你可以在这里找到一些:如果你需要的话,你可能需要谷歌/在链中搜索其他的。

https://pki.google.com/ https://www.geotrust.com/resources/root-certificates/index.html

它们是这样的:

(注意:这是一个图像,所以人们不会简单地从stackoverflow复制/粘贴证书)

在这个文件中有了正确的证书之后,重新启动apache并进行测试。


您可以尝试重新安装ca-certificates包,或者像这里描述的那样显式地允许出现问题的证书。