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

时间:2012-09-06 17:15:41

标签: 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中发现了很多与同一问题有关的问题,他们中的大多数人说解决方案是使用CURLOPT_CAINFO cURL选项提供一捆CA.我下载了这个插件,并且目前附带了http://curl.haxx.se/ca/cacert.pem最新版本(2012年6月28日转换)。这解决了我收到的大部分问题。

现在的问题是,我刚刚收到另一份付款失败的报告,错误是相同的:SSL certificate problem, verify that the CA cert is OK.。有趣的是,现在的解决方案是删除 CURLOPT_CAINFO选项。我想知道是否有解释。我认为使用更新的CA捆绑包(例如我下载的捆绑包)是一般解决方案,但似乎不是这样。

这种问题的一般解决方案是什么?什么可以解释使用更新的CA捆绑导致SSL证书问题,而不是修复它们?。

这是cURL configuartion:

<?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 Class 3公共主要证书颁发机构 - G5
  • VeriSign Class 3扩展验证SSL CA
  • www.paypal.com

我可以确认 VeriSign Class 3公共主要证书颁发机构的证书 - G5 包含在我使用的http://curl.haxx.se/ca/cacert.pem版本中。

感谢您的帮助。

2 个答案:

答案 0 :(得分:11)

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

这将使您的通信对潜在的中间人攻击开放,从而首先破坏了使用SSL的目的。

此问题的一个可能的解释是,设置CURLOPT_CAINFO(特别是错误的证书路径 - 我会对其进行双重检查)会覆盖服务器上的默认路径。

删除设置后,它将恢复为默认设置(可以在PHP中设置)。

要记住的另一件事是CURLOPT_CAINFO是绝对路径。

答案 1 :(得分:3)

查看此网址

http://davidwalsh.name/php-ssl-curl-error

或尝试

$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);