PHP Curl设置SSL版本

7

三天来我无法连接到PayPal沙盒。我发现他们可能已经停用了对SSLv3的支持。因此,我尝试通过设置我的curl请求中的SSL版本来更改:

curl_setopt($curl, CURLOPT_SSLVERSION,1); # 1 = TLSv1

但是它仍然给我相同的错误提示:
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

不知道为什么脚本仍在使用SSLv3协议?

我正在使用php 5.5版本和以下curl版本(目前正在要求我的托管服务提供商[1&1]升级到更新的版本)

curl 7.21.0 (i486-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.15 libssh2/1.2.6 Protocols: dict file ftp ftps http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

3个回答

6
问题在于PayPal已停止支持SSLv3、TLS 1.0和TLS 1.1,现在仅支持TLS 1.2,但cURL构建的OpenSSL版本(0.9.8o)不支持TLS。目前,你只能希望主机能够更新OpenSSL、cURL和PHP到新版本(1.0+)的OpenSSL。目前来看,你的cURL客户端不支持PayPal所需的TLS,除了更新OpenSSL之外,没有其他解决方法。

1
唯一的解决方案是升级到包含OpenSSL 1.0+的新版本CURL。感谢您的建议 :) - Ephenodrom

4

我遇到了同样的问题。

    <?php
error_reporting(E_ALL);
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_VERBOSE, 1);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_URL, 'https://api-3t.sandbox.paypal.com/nvp');

$response =    curl_exec($curl);
var_dump($response);
exit;

响应:

bool(false)

而且没有错误日志!

所以我写了一个小脚本:

<?php
error_reporting(E_ALL);
var_dump(file_get_contents('https://api-3t.sandbox.paypal.com/nvp'));

这是日志中记录的内容:

[12-Feb-2016 15:56:19] PHP Warning:  file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure in /xxx/yyy.php on line 3
[12-Feb-2016 15:56:19] PHP Warning:  file_get_contents(): Failed to enable crypto in /xxx/yyy.php on line 3
[12-Feb-2016 15:56:19] PHP Warning:  file_get_contents(https://api-3t.sandbox.paypal.com/nvp): failed to open stream: operation failed in /xxx/yyy.php on line 3

我的解决方案是:

  1. 更新(1.0+)版本的OpenSSL。
  2. 重新编译Curl。
  3. 重新编译PHP并使用新的CURL。
  4. 确保Curl SSL版本是OpenSSL/(1.0+)。

SSL版本 OpenSSL/1.0.1e - 良好

SSL版本 NSS/3.13.6.0 - 不好

我正在运行CentOS,以下是我的更新步骤:

  1. 更新OpenSSL:

    openssl version

如果低于1.0,则运行:yum update openssl 确保已经更新

  1. 重新安装PHP。因此,请保存php.ini文件
  2. 通过以下命令列出所有已安装的PHP模块:

    yum list installed | grep php

保存输出!

  1. yum erase php
  2. yum erase php-curl
  3. yum install php
  4. yum install php-curl

  5. 重新启动apache或fpm,如果你很幸运,一切都会正常工作

  6. 还原php.ini配置和PHP模块:yum install php-pgsql;yum install php-gd;等等

但是,如果您的软件包存储库过时或已安装了NSS SSL绑定的Curl库,则可以手动下载和编译Curl库。我使用了捆绑在php-devel软件包中的phpize工具。所以我的问题是:

cURL Information    7.19.7 
SSL Version     NSS/3.13.6.0

以下是我进行的更改:

cURL Information    7.22.0 
SSL Version     OpenSSL/1.0.1e 
  1. 更新OpenSSL:

    openssl version

如果版本低于1.0,请运行yum update openssl确保已经更新。

  1. 重新安装PHP,请保存php.ini文件。
  2. 通过以下命令列出所有已安装的PHP模块:

    yum list installed | grep php

保存输出结果!

  1. yum erase php
  2. yum erase php-curl
  3. yum install php-devel
  4. 使用rpm -qa --queryformat '%{version}' php打印PHP版本,并找到可以下载相同PHP源代码的位置。
  5. 以下bash脚本将安装特定的curl库:

<pre>
#!/bin/bash

PHP_VERSION=$(rpm -qa --queryformat '%{version}' php)

CURL_VERSION=7.22.0

#echo $CURL_VERSION
#exit

#wget --no-check-certificate http://mirror.cogentco.com/pub/php/php-${PHP_VERSION}.tar.gz -O /tmp/php-${PHP_VERSION}.tar.gz
wget --no-check-certificate http://museum.php.net/php5/php-${PHP_VERSION}.tar.gz -O /tmp/php-${PHP_VERSION}.tar.gz
wget --no-check-certificate http://curl.haxx.se/download/curl-${CURL_VERSION}.tar.gz -O /tmp/curl-${CURL_VERSION}.tar.gz

cd /tmp; tar xzf php-${PHP_VERSION}.tar.gz
cd /tmp; tar xzf curl-${CURL_VERSION}.tar.gz

cd curl-${CURL_VERSION}
./configure
make
make install

cd /tmp; rm -rf curl-${CURL_VERSION}*

sleep 2

cd /tmp/php-${PHP_VERSION}/ext/curl/
phpize
./configure
make
make install

cd /tmp; rm -rf php-${PHP_VERSION}*

</pre>

  1. 重新启动 Apache 或 FPM,如果幸运的话,您就可以让所有东西正常工作。
  2. 恢复 PHP.ini 配置和 PHP 模块:yum install php-pgsql; yum install php-gd; 等等。

1
完美,我想让LibCurl使用OpenSSL而不是NSS,这有助于我修复它以调整php libcurl以使用OpenSSL。
我的Centos7 PHP 5.6正在使用。
php -r "print_r(curl_version());" | grep ssl_version
[ssl_version_number] => 0
[ssl_version] => NSS/3.19.1 Basic ECC

经过上述修复后,它显示出了我想要的结果。
php -r "print_r(curl_version());" | grep ssl_version
[ssl_version_number] => 0
[ssl_version] => OpenSSL/1.0.1f

这是我在Centos7上使用的已修订脚本,使用的是PHP 5.6.17

#!/bin/bash
PHP_VERSION=$(rpm -qa --queryformat '%{version}' php56)
CURL_VERSION=$(curl -V|head -1|awk '{print $2}')
wget --no-check-certificate http://mirror.cogentco.com/pub/php/php-5.6.17.tar.bz2 -O /tmp/php-${PHP_VERSION}.tar.bz2
wget --no-check-certificate http://curl.haxx.se/download/curl-${CURL_VERSION}.tar.gz -O /tmp/curl-${CURL_VERSION}.tar.gz

cd /tmp; tar xjf php-${PHP_VERSION}.tar.bz2
cd /tmp; tar xzf curl-${CURL_VERSION}.tar.gz

cd curl-${CURL_VERSION}
./configure
make
make install

cd /tmp; rm -rf curl-${CURL_VERSION}*

sleep 2

cd /tmp/php-${PHP_VERSION}/ext/curl/
phpize
./configure
make
make install

cd /tmp; rm -rf php-${PHP_VERSION}*

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接