Php 将CURLOPT_CAINFO与更新的CA包一起使用会导致证书验证失败

Php 将CURLOPT_CAINFO与更新的CA包一起使用会导致证书验证失败,php,curl,Php,Curl,我使用cURL验证WordPress插件中的PayPal事务。最近,我开始收到关于用户无法完成购买过程的错误报告,因为交易无法验证。我将错误跟踪到: SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed 我在StackOverflow中发现了许多与同一问题

我使用cURL验证WordPress插件中的PayPal事务。最近,我开始收到关于用户无法完成购买过程的错误报告,因为交易无法验证。我将错误跟踪到:

SSL certificate problem, verify that the CA cert is OK. Details: 
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
我在StackOverflow中发现了许多与同一问题相关的问题,大多数人说解决方案是使用
CURLOPT_CAINFO
cURL的选项提供一个CA包。我下载了插件的最新版本(于2012年6月28日转换),目前随插件一起发布。这解决了我收到的大部分问题

现在的问题是,我刚刚收到另一份付款失败的报告,错误是相同的:
SSL证书问题,请验证CA证书是否正常。
。有趣的是,现在的解决方案是删除
CURLOPT_CAINFO
选项。我想知道这是否有什么解释。我认为使用更新的CA包(比如我下载的那个)是一个通用的解决方案,但似乎不是这样

这类问题的一般解决方案是什么?还有什么可以解释使用更新的CA捆绑包会导致SSL证书问题,而不是修复这些问题

这是cURL配置:

<?php
    $ch = curl_init("https://www.paypal.com/cgi-bin/webscr");
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_VERBOSE, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
?>

更新: www.paypal.com的证书由VeriSign签署。证书层次结构(如Firefox中所示)是:

  • VeriSign 3级公共初级认证机构-G5
  • VeriSign Class 3扩展验证SSL CA
  • www.paypal.com
我可以确认VeriSign 3级公共初级证书颁发机构G5的证书包含在我使用的版本中

谢谢您的帮助。

请查看此url

或者试试看

$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,'https://thirdparty.com/token.php'); //not the actual site
curl_setopt($ch,CURLOPT_TIMEOUT,60);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,'customer_id='.$cid.'&password='.$pass);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true); 
curl_setopt($ch,CURLOPT_CAINFO,'mozilla.pem'); /* fixed! */
$result = curl_exec($ch);
if(empty($result)) { /* error: nothing returned */ } else { /* success! */ }
curl_close($ch);

如果您遇到此问题,请不要按照某人的建议禁用对等和主机验证

这将使您的通信对潜在的中间人攻击敞开大门,从一开始就破坏了使用SSL的目的

对此问题的一个可能解释是,设置
CURLOPT_CAINFO
(尤其是设置不正确的证书路径-我会仔细检查一下)会覆盖服务器上的默认路径

删除该设置后,它将返回默认设置(可以在PHP中设置)


另一件需要记住的事情是,
CURLOPT_CAINFO
是一条绝对路径。

Tx@AbidHussain,我相信mozzila.pem是我使用的同一个文件,但名称不同。在我所看到的大多数情况下,使用该捆绑包修复了这个问题,但它也会破坏其他用户的功能。这就是我现在想要理解的。谢谢@Tim_K。我仍然在使用对等和主机验证。当时我正在开发WordPress插件,在我引入自定义证书包之后,只有少数主机出现SSL问题。我从来没有想到原因;因为大多数其他主机都在工作。最后,我使用自定义证书包处理请求,如果出现问题,我会使用默认的证书包(删除
CURLOPT_CAINFO
设置)(您仍然有这个问题吗?)只是为了缩小查询范围:您是否从同一主机为每个请求连接PayPal?也就是说,来自同一台机器的同一源代码偶尔会抛出此错误?很抱歉回答得太晚。上面的代码是WordPress插件的一部分。我在同一源代码中看到了不同的结果,但机器不同。一些用户在使用自定义证书捆绑包时报告了问题,其他用户在使用默认捆绑包时报告了问题。我的解决方案是支持这两种方案:尝试使用定制包,并在出现错误的情况下重复请求。您描述的解决方案似乎是您的最佳选择。如果不跟踪每个用户的php+curl版本,就很难找出原因:是权限问题、遗留API、历史上的php/curl错误还是主机配置错误?太多的因素。我只想说,我认为选择定制的最新CA包是一种很好的做法,对于配置良好的现代php环境来说应该是可靠的。