Perl,LWP "certificate verify failed" 和 paypal.com

Perl, LWP "certificate verify failed" with paypal.com

不能 100% 确定这是 Perl 问题,但似乎是。我有一个与 PayPal 连接以验证交易的 IPN 脚本。直到昨天我安装 LWP::Protocol::https 之前它都运行良好。从那以后,它一直因错误而失败:

Can't connect to www.paypal.com:443 (certificate verify failed)

LWP::Protocol::https::Socket: SSL connect attempt failed error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed at /usr/local/share/perl5/LWP/Protocol/http.pm line 47.

运行 GET https://www.paypal.com 来自 bash(使用 LWP)产生相同的错误消息。 OTOH,运行 GET https://www.gmail.com 成功了。 运行 openssl s_client -host paypal.com -port 443 returns(除其他外)Verify return code: 0 (ok)curl "https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate" 成功收到来自 PayPal 的回复。所以它似乎是特定于 Perl 的。

模块版本:

LWP 6.13
LWP::Protocol::https 6.06
IO::Socket::SSL 2.015
Mozilla::CA 20141217 (note: I've tried the script both using Mozilla::CA and without it... results have been the same)

如果还有其他相关模块,请告诉我。 Perl 版本是 5.10.1。服务器 OS 是 RHEL 6。

Mozilla::CA 20141217 (note: I've tried the script both using Mozilla::CA and without it... results have been the same)

简而言之: 我不知道 "without it" 对 RHEL6 意味着什么,但请使用 Mozilla::CA 20130114 或从 http://curl.haxx.se/docs/caextract.html.

链接的 "older ca-bundle" 再试一次

详情: 您从 www.paypal.com

获得的证书链
[0] www.paypal.com
[1] Symantec Class 3 EV SSL CA - G2
[2] VeriSign Class 3 Public Primary Certification Authority - G5

链中的最后一个证书由 1024 证书签名

/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority

自从去年底 Mozilla 删除了 1024 位证书后,您将不会再在当前的 Mozilla::CA 中找到它们。但是浏览器不需要旧证书,因为它们已经基于证书 [0] 和 [1] 创建了信任链,因为它们使用内置证书而不是服务器发送的证书 [2]。

虽然这个较新的内置证书也包含在 Mozilla::CA 中,但由于 OpenSSL 验证证书的方式存在长期存在的错误,因此不会使用它:它总是会尝试验证最长的链,而不是检查是否可以使用更短的链。

有关此问题的更多详细信息,请参阅

这个问题可以通过使用 OpenSSL 1.02(4 个月前发布,可能还没有在 RHEL 中)引入的标志 X509_V_FLAG_TRUSTED_FIRST 或使用更新但尚未发布的 OpenSSL 版本来解决他们最终解决了问题(参见 https://rt.openssl.org/Ticket/Display.html?id=3637&user=guest&pass=guest)。

这个问题可以通过让旧的 1024 位 CA 证书仍然可用来解决,即使用旧的 Mozilla::CA 或 CA 捆绑包或使用通常包含这些旧 CA 的系统 CA 存储。另请参阅:

  • A current bug report 反对 IO::Socket::SSL 默认情况下使用 X509_V_FLAG_TRUSTED_FIRST(如果可用)。此标志设置为 2.016(尚未发布),但需要 Net::SSLeay 版本导出此标志(尚未发布)和 OpenSSL 1.02(未包含在 RHEL 中)。
  • A pull request against LWP 使用系统上的默认 CA 而不是 Mozilla::CA。这也可能会为您解决问题。请注意,Debian/Ubuntu 包含一个类似的补丁。我不知道 RHEL 附带的 LWP 版本。