我正在使用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等设置更改可以解决这个问题。
来源: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
上面的解决方案很好,但是如果您正在使用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引用。)
当我试图让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并进行测试。