Paypal访问 - SSL证书:无法获得本地颁发者证书

时间:2013-07-04 21:27:20

标签: php curl ssl paypal

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

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才能使用PayPal访问?

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

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

4 个答案:

答案 0 :(得分:119)

正确的解决方案是修复您的PHP设置..将CURLOPT_SSL_VERIFYPEER设置为false是一个快速入侵,但是当您通过其证书颁发机构禁用证书验证时,它是错误的。这会让你暴露在中间人的攻击中。

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

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

答案 1 :(得分:12)

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

CURLOPT_SSL_VERIFYPEER, false

到您的$options然而正确的方法是启用验证。

安全通知

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

请注意,通过将curl.cainfo设置为CURLOPT_SSL_VERIFYPEER,您解决问题!你正在努力。这一切都与安全有关,所以暂时这样做很好,但是在生产中将其部署在生产上并不明智,礼貌地说,因为你会对Man In The Middle Attack开放。你被警告了。

答案 2 :(得分:5)

我遇到了同样的问题

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

我使用了在此处找到的paypal的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证书的目的。

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

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

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

  • Verisign Class 1公共主要证书颁发机构
  • Verisign Class 1公共主要证书颁发机构 - G2
  • Verisign Class 1公共主要证书颁发机构 - G3
  • Verisign Class 2公共主要证书颁发机构 - G2
  • Verisign Class 2公共主要证书颁发机构 - G3
  • Verisign Class 3 Public Primary Certification Authority
  • Verisign Class 4公共主要证书颁发机构 - G2

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

我没有时间调试并确切知道需要哪个证书,所以我只包括所有证书。

对于将来遇到此问题的任何人,我建议从curl获取最新的证书,并逐一添加上面列表中的证书,直到错误消失为止。

以下是其中一些verisign证书的链接(您可能需要针对未列出的其他证书进行google):www.symantec.com/page.jsp?id = root

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

openssl s_client -connect paypal.com:443 -showcerts

如果有人对这个问题有进一步的了解,请评论,因为我花了几个小时来计算上述所有内容。

答案 3 :(得分:2)

  

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

表示cUrl不信任Verisign,即担保PayPal的证书颁发机构。正如Marc B所评论的那样,cUrl不再对任何证书颁发机构提供信任。

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

CURLOPT_SSL_VERIFYPEER => 0

要了解如何配置cUrl以使其信任Verisign,请阅读cUrl documentation