【问题标题】:Using CURLOPT_CAINFO with updated CA bundle causes certificate verify failed将 CURLOPT_CAINFO 与更新的 CA 捆绑包一起使用会导致证书验证失败
【发布时间】:2012-09-06 17:15:41
【问题描述】:

我使用 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 配置:

<?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 中所示)是:

  • 威瑞信 3 类公共主要证书颁发机构 - G5
  • 威瑞信 Class 3 扩展验证 SSL CA
  • www.paypal.com

我可以确认 VeriSign Class 3 Public Primary Certification Authority - G5 的证书包含在我正在使用的 http://curl.haxx.se/ca/cacert.pem 版本中。

感谢您的帮助。

【问题讨论】:

  • (您还有这个问题吗?)只是为了缩小查询范围:您是否为每个请求都从同一主机连接到 PayPal?意思是,相同的源代码,来自同一台机器,偶尔会抛出这个错误?
  • 抱歉,回答迟了。上面的代码是 WordPress 插件的一部分。我看到使用相同源代码但机器不同的不同结果。一些用户在使用自定义证书包时报告了问题,而其他用户在使用默认包时报告了问题。我的解决方案是支持这两种情况:尝试使用自定义捆绑包并在没有它的情况下重复请求,以防出错。
  • 有趣的问题。您描述的解决方案似乎是您最好的选择。如果不跟踪每个用户的 php + curl 版本,就很难找出原因:是权限问题、遗留 API、历史 php/curl 错误还是配置错误的主机?因素太多。可以这么说,我认为更喜欢自定义的最新 CA 包是一种很好的做法,并且对于配置良好的现代 php 环境应该是可靠的。

标签: php curl


【解决方案1】:

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

这将使您的通信容易受到潜在的中间人攻击,从而破坏了使用 SSL 的初衷。

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

一旦你删除了设置,它就会恢复到它的默认值(可以在 PHP 中设置)。

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

【讨论】:

  • 谢谢@Tim_K。我仍在使用对等和主机验证。那时我正在开发一个 WordPress 插件,在我引入自定义证书包之后只有少数主机出现 SSL 问题。我从来没有想过原因;因为大多数其他主机都在工作。我最终使用自定义证书包进行请求,如果出现问题,我会退回使用默认的(删除CURLOPT_CAINFO 设置)。
【解决方案2】:

查看此网址

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

【讨论】:

  • Tx @AbidHussain,我相信 mozzila.pem 是我使用的同一个文件,但名称不同。在我见过的大多数情况下,使用该捆绑包解决了这个问题,但它也对其他用户造成了破坏。这就是我现在想要理解的。
猜你喜欢
  • 2023-04-10
  • 2013-09-13
  • 2019-01-26
  • 1970-01-01
  • 2018-01-03
  • 2023-04-09
  • 1970-01-01
  • 2012-05-02
  • 1970-01-01
相关资源
最近更新 更多