HTTPS和SSL3_GET_SERVER_CERTIFICATE:证书validation失败,CA正常

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

现在,当我curl启用HTTPS的网站,我得到以下exception

致命错误:带有消息“cURL resource:Resource id#55”的未捕获exception“RequestCore_Exception” cURL错误:SSL证书问题,请validationCA证书是否正确。 详细信息:错误:14090086:SSL例程:SSL3_GET_SERVER_CERTIFICATE:证书validation失败(60)'

大家都build议使用PHP代码中的一些特定的curl选项来解决这个问题。 我认为这不应该是这样的。 因为我对旧版本的XAMPP没有任何问题,只是在安装新版本后才发生。

我需要帮助来弄清楚PHP安装中的设置有什么变化,Apache等可以解决这个问题。

curl用于包含可接受CA的列表,但不再捆绑任何CA证书。 所以默认情况下,它会拒绝所有的SSL证书为不可validation的。

你必须得到你的CA的证书并指向它。 有关服务器SSL证书详情,请参阅cURLS的详细信息 。

这在Windows中是一个很常见的问题。 你只需要设置cacert.pem curl.cainfo

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

  1. 下载https://curl.haxx.se/ca/cacert.pem并保存在某个地方。;
  2. 更新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证书的所有validation。

资料来源: http : //ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html

Curl:SSL证书问题,请validationCA证书是否正确

2006年4月7日

使用Curl打开安全url时,可能会出现以下错误:

SSL证书问题,请validationCA证书是否正确

我会解释为什么错误和你应该做的。

摆脱错误的最简单方法是将以下两行添加到脚本中。 这个解决scheme构成了一个安全风险。

 //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检查是否存在通用名称,并validation它是否与所提供的主机名相匹配。

CURLOPT_SSL_VERIFYPEER :FALSE停止CURLvalidation对等方的证书。 可以使用CURLOPT_CAINFO选项指定要validation的替代证书,或者可以使用CURLOPT_CAPATH选项指定证书目录。 如果CURLOPT_SSL_VERIFYPEER被禁用(默认为2),则CURLOPT_SSL_VERIFYHOST也可能需要为TRUE或FALSE。 将CURLOPT_SSL_VERIFYHOST设置为2(这是默认值)将保证提供给您的证书具有与用于访问远程资源的URN相匹配的“通用名称”。 这是一个健康的检查,但不能保证你的程序不被破坏。

进入“中间人”

相反,您的程序可能会误导到另一台服务器。 这可以通过多种机制来实现,如dns或arp中毒(这是另一天的故事)。 入侵者还可以用程序所期望的相同“comon名称”自签名证书。 沟通仍然是encryption的,但你会泄露你的秘密骗子。 这种攻击被称为“中间人”

击败“中间人”

那么,我们需要validation提交给我们的证书是否真实。 我们通过将其与我们合理的信任证书进行比较来做到这一点。

如果远程资源受到主要CA(例如Verisign,GeoTrust等)颁发的证书的保护,则可以安全地比较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

上面的解决scheme很好,但是如果你使用的是WampServer,你可能会发现在php.ini中设置curl.cainfovariables不起作用。

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

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

第一种显然是用于通过Web浏览器调用PHP文件的,而第二种是在通过命令行或shell_exec()调用命令时使用的。

TL; DR

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

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

如果您确定服务端点URL,请通过浏览器打开它,手动将该证书保存为“带连接(PEM)的X 509证书”格式。 将这个证书文件指向

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

当为CURLOPT_CAINFO设置curl选项时,请记住使用单引号,使用双引号只会导致另一个错误。 所以你的select应该是这样的:

 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参考,所以当我使用关键字curlsearch时,我可以在一个区域find两个curl参考。

为了所有圣洁的爱…

在我的情况下,我不得不将openssl.cafile PHPconfigurationvariables设置为PEM文件path。

我相信有很多系统在PHP的configuration中设置curl.cainfo正是我所需要的,但是在我正在使用的环境中,这是eboraas / laravel docker容器,它使用Debian 8(jessie )和PHP 5.6,设置该variables没有办法。

我注意到php -i的输出没有提到有关特定configuration设置的任何内容,但是它确实有几行关于openssl 。 有一个openssl.capathopenssl.cafile选项,但只是设置第二个允许curl通过PHP最终是好的HTTPS的URL。

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

我通过在/etc/php.d/curl.ini上设置curl.cainfo来解决

https://gist.github.com/reinaldomendes/97fb2ce8a606ec813c4b

当我尝试使用GuzzleHttp(Mac上的php + apache)从www.googleapis.com获取页面时,我结束了这个工作。

这是我的最终解决scheme,以防万一。

看看证书链,无论域名给你这个错误。 对我来说,这是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 

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

你可以在这里find其中的一些: 如果你需要,你可能需要谷歌/search链中的其他人。

他们看起来像这样:

示例证书图像

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

一旦正确的证书在这个文件中,重新启动Apache并testing。

Interesting Posts