php - Paypal 沙盒 SSL 握手错误

标签 php ssl curl paypal tls1.2

对 Paypal 沙箱的 Curl 请求失败

error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

这个症状已经是许多 stackoverflow 问题的主题 - 我已经在几个网站上解决了它,但在这种情况下,我还没有将答案汇总在一起以获得有效的解决方案。

问题域是 TLSv1.2 的实现 - 它在 Paypal 沙箱中处于事件状态并且即将上线。

此错误通常发生在以下任一情况下

  • TLSv1.2 不可用,因为站点上的 curl/openssl 版本试图 调用 Paypal,或
  • 在对 Paypal 的 curl 调用中未使用它,因此必须在 curl 选项中强制使用

但是,这可以通过对 tlstest.paypal.com 的 curl 调用来检查,在这种情况下调用 return

PayPal_Connection_OK

没有和有

curl_setopt($curl, CURLOPT_SSLVERSION, 6);

表明 TLSv1.2 不仅可用而且默认使用。由于网站报告的 curl/openssl 版本不会出现这种情况,因此我推断安全更新已被反向移植。

插入调试信息已确认这两个调用(除了 url)之间的唯一区别是这些选项值

     "CURLOPT_POST":true,
     "CURLOPT_POSTFIELDS":"USER=uuuuuu&PWD=pppppp&SIGNATURE=ssssss&VERSION=204&METHOD=GetBalance&RETURNALLCURRENCIES=1",

我的推断是握手问题在于数据的加密,因此我一直在考虑设置 CURLOPT_SSL_CIPHER_LIST。一个建议是

curl_setopt($curl, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');

在这种情况下,它不会改变握手错误。

我也研究过设置特定的密码,但没有找到任何不会导致错误的值

failed setting cipher list

我尝试使用 openssl_get_cipher_methods() 获取调用站点上的密码列表

'AES-128-CBC','AES-128-CFB','AES-128-CFB1','AES-128-CFB8','AES-128-OFB','AES-192-CBC','AES-192-CFB','AES-192-CFB1','AES-192-CFB8','AES-192-OFB','AES-256-CBC','AES-256-CFB','AES-256-CFB1','AES-256-CFB8','AES-256-OFB','BF-CBC','BF-CFB','BF-OFB','CAST5-CBC','CAST5-CFB','CAST5-OFB'

但这些都不符合我在 https://www.openssl.org/docs/manmaster/man1/ciphers.html 上找到的 openssl 名称我打算用它来映射到从 https://github.com/curl/curl/blob/master/lib/vtls/nss.c 中获取的 curl 名称通过 RFC 名称。

我从这里去哪里?

[编辑添加:]

  • 操作系统 Linux 2.6.26-2-amd64
  • PHP 5.3.19-1~dotdeb.0 (Zend: 2.3.0) [我被告知,但没有解释,这是可用的最高版本]
  • OpenSSL 0.9.8o 2010 年 6 月 1 日
  • curl 版本 7.21.0

我已经尝试通过添加选项值来针对 tlstest.paypal.com 向 curl 请求添加正文进行进一步测试:

  "CURLOPT_POST":true,
  "CURLOPT_POSTFIELDS":"A=B&C=D",

令人惊讶的是,它仍然返回成功的响应。

所以我现在已经使用 https://www.ssllabs.com/ssltest/ 比较了两台服务器可用的密码套件不同,服务器的首选顺序也不同。在 tlstest 上,有更安全的密码可用,它们是首选,而在沙盒上,弱密码排在第一位。

所以我仍然认为解决方案可能是指定一个密码列表,并且已经通过这个最新的 ssltest 信息希望找到哪个可以在 tlstest.paypal.com 上工作。鉴于此,我现在尝试了各种方法(并了解到此选项的格式取决于 openssl 的构建方式)但我已经测试了测试报告的所有 TLSv1.2 密码套件,结果如下:

//  $cipher = 'AES128-SHA'; //handshake error
//  $cipher = 'AES256-SHA'; //handshake error
//  $cipher = 'ECDHE-RSA-AES128-SHA'; //handshake error
//  $cipher = 'ECDHE-RSA-AES256-SHA'; //handshake error
//  $cipher = 'AES128-SHA256'; //failed setting cipher list
//  $cipher = 'AES256-SHA256'; //failed setting cipher list
//  $cipher = 'AES128-GCM-SHA256'; //failed setting cipher list
//  $cipher = 'AES256-GCM-SHA384'; //failed setting cipher list
//  $cipher = 'ECDHE-RSA-AES128-SHA256'; //failed setting cipher list
//  $cipher = 'ECDHE-RSA-AES256-SHA384'; //failed setting cipher list
//  $cipher = 'ECDHE-RSA-AES128-GCM-SHA256'; //failed setting cipher list
    $cipher = 'ECDHE-RSA-AES256-GCM-SHA384'; //failed setting cipher list
    curl_setopt($curl, CURLOPT_SSL_CIPHER_LIST, $cipher);

来自 tlstest.paypal.com - 这有点令人失望,因为我希望其中一个可以工作,但不能在沙盒中使用。

最佳答案

所以我的客户的托管支持终于“告白了”:

Our GRID platform which currently host's the site does not include ciphers for TLS1.2.

所以@hanshenrik 是正确的。我推断,当您针对 tlstest.paypal.com 进行测试时,如果 TLS 协议(protocol)的正确版本不可用,它就会失败。然而,成功并不表示所有元素都存在以成功正确调用 Paypal 沙箱 - 特别是密码套件未在 tlstest 上检查,即使将正文添加到调用并指定此选项也是如此:

curl_setopt($curl, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');

您必须指定单独的密码才能让 tlstest 抛出握手错误。

关于php - Paypal 沙盒 SSL 握手错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49095435/

相关文章:

python - 使用python访问具有PKI安全性的站点

python - ssl.SSLError : [SSL: SSLV3_ALERT_BAD_RECORD_MAC] sslv3 alert bad record mac

Python 请求获取一个应该正常工作的 URL 的错误页面

curl - 使用 s_client 而不是 curl 访问带有客户端证书的服务器?

curl - 对 JIRA 进行身份验证时出现 curl 错误

php - fwrite 不会断行

php - php jquery中Json的数据

php - 如何在 WordPress 仪表板上添加已注册侧边栏的文本小部件?

php - CodeIgniter 中的动态 URL?

java - 使用 SSL/TLS 和 keystore 配置 Jetty