44

我正在使用 cUrl 和 PHP 向服务器发出请求(用于访问贝宝)

Paypal 开发者网站从未提及使用 PayPal 访问 API 需要 SSL 证书,但是我用来请求令牌的代码如下:

$options = array(
                CURLOPT_URL => $url,
                CURLOPT_POST => 1,
                CURLOPT_VERBOSE => 1,
                CURLOPT_POSTFIELDS => $postvals,
                CURLOPT_RETURNTRANSFER => 1,
                CURLOPT_SSLVERSION => 3
);

curl_setopt_array($ch, $options);

$response = curl_exec($ch); 
echo curl_error($ch);

此回显输出以下错误:

SSL certificate problem: unable to get local issuer certificate

我的问题是:

1) 如果我只需要获取用户电子邮件,我是否需要 SSL 才能使用贝宝访问?

2) 如果我不需要 SSL,为什么会出现此错误?

PS:端点如下:https ://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/tokenservice

4

4 回答 4

122

正确的解决方案是修复您的 PHP 设置。将 CURLOPT_SSL_VERIFYPEER 设置为 false 是一种快速破解方法,但这是错误的,因为您禁用了证书颁发机构的证书验证。这会使您面临中间人攻击。

很容易修复(php 5.3.7 或更高版本) - 下载具有最新证书颁发机构的列表文件,并将此设置添加到您的php.ini
curl.cainfo=<path-to>cacert.pem

重新启动您的网络服务器,它会工作!

于 2013-10-03T02:09:08.720 回答
12

您可以通过添加以下内容来禁用 SSL 验证(从 cURL 7.10 开始默认启用):

CURLOPT_SSL_VERIFYPEER, false

到您的$options但是正确的方法是保持启用验证。

安全须知

如果远程站点使用已知 CA 颁发的证书但验证仍然失败,则很可能证书在远程服务器上设置不正确(缺少中间证书等)。或者,您的系统不知道使用的已签署目标证书的证书颁发机构。在这种情况下,您应该使用php.ini's curl.cainfo文档)指向具有所有受支持 CA 的有效 PEM 文件 - 这将使您的设置正确验证颁发者链。

请注意,设置CURLOPT_SSL_VERIFYPEERfalse您并不能解决问题!你正在解决它。这都是关于安全性的,所以暂时可以这样做,但是礼貌地说,将其部署在生产环境中并不明智,因为您将对中间人攻击持开放态度。你被警告了。

于 2013-07-04T21:44:44.320 回答
5

我有同样的问题

Can't connect to PayPal to validate IPN message: SSL certificate: unable to get local issuer certificate

我使用了在此处找到的贝宝 github 上生成的代码示例(我使用了 PHP):https ://github.com/paypal/ipn-code-samples

我下载了两个证书并尝试从 curl 进行测试: http: //curl.haxx.se/docs/caextract.html

经过大约 2 小时的测试(使用 paypal 的 ipn 模拟器)和谷歌搜索,发现无法在上面测试 paypal ipn localhost,所以我将代码实时推送并尝试测试,但仍然出现相同的错误(即使权限设置为 777)。

当我设置CURLOPT_SSL_VERIFYPEER, false时,它起作用了,但这会破坏拥有 ssl 证书的目的。

在窥探我服务器的文件后,我curl-ca-bundle.crt在我的 PHP 文件夹中找到了一个文件。我决定将CURLOPT_CAINFO我的 paypal ipn 脚本中的硬编码到该路径。它终于奏效了!

我注意到这个较旧的 .crt 文件包含一些不在 curl 网站上的最新 .crt 文件中的证书。这是一堆来自verisign class 1, verisign class 2, verisign class 3 and verisign class 4.

这是我添加到 curl 的 .crt 文件中的证书名称的完整列表:

  • 威瑞信 1 类公共主要证书颁发机构
  • 威瑞信 1 类公共主要证书颁发机构 - G2
  • 威瑞信 1 类公共主要证书颁发机构 - G3
  • 威瑞信 2 类公共主要证书颁发机构 - G2
  • 威瑞信 2 类公共主要证书颁发机构 - G3
  • 威瑞信 3 类公共主要证书颁发机构
  • 威瑞信 4 类公共主要证书颁发机构 - G2

这可能与@Andomar 所说的有关-paypal 的verisign 证书不包含在默认(默认情况下,我的意思是curl 的默认)安全证书列表中。

我没有时间调试和弄清楚到底需要哪个证书,所以我只包括了所有证书。

对于以后遇到这个问题的人,我建议从 curl 获取最新的证书,并在上面的列表中逐个添加证书,直到错误消失。

这是其中一些威瑞信证书的链接(您可能需要谷歌搜索未列出的其他证书):www.symantec.com/page.jsp?id=roots

注意*:要查看 paypal 的当前证书,您可以在终端中运行此命令:

openssl s_client -connect paypal.com:443 -showcerts

如果有人对这个问题有进一步的了解,请发表评论,因为我花了几个小时来弄清楚以上所有内容。

于 2014-12-15T22:40:10.177 回答
2

SSL 证书问题:无法获取本地颁发者证书

意味着 cUrl 不信任为 PayPal 提供担保的证书颁发机构 Verisign。正如 Marc B 评论的那样,cUrl 不再信任任何证书颁发机构。

您可以使用以下选项绕过证书链验证:

CURLOPT_SSL_VERIFYPEER => 0

要阅读如何配置 cUrl 以使其信任 Verisign,请阅读cUrl 文档

于 2013-07-04T21:34:11.060 回答