[php] HTTPS和SSL3_GET_SERVER_CERTIFICATE:证书验证失败,CA正常



Answers

这在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");
Question

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

现在当我卷曲启用HTTPS的网站时,我收到以下异常

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

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

我需要帮助来弄清我的PHP安装中哪些设置发生了变化,Apache等可以解决这个问题。




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

卷曲:SSL证书问题,请验证CA证书是否正确

2006年4月7日

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

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被禁用(默认为2),则CURLOPT_SSL_VERIFYHOST也可能需要为TRUE或FALSE。 将CURLOPT_SSL_VERIFYHOST设置为2(这是默认值)会保证提供给您的证书具有与用于访问远程资源的URN相匹配的“通用名称”。 这是一项健康的检查,但不能保证你的程序没有被拒绝。

进入'中间人'

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

击败'中间人'

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

如果远程资源受到其中一个主要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 : http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html




为了所有圣洁的爱...

在我的情况下,我必须将openssl.cafile PHP配置变量设置为PEM文件路径。

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

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




当我试图从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

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

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

他们看起来像这样:

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

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




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

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

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





Links