PayPal:SSL connect error 解决方案
米扑代理为了方便国外客户购买,支持 PayPal 在线付款,但是 PayPal 要求网站 https 升级到 SSL TLSv1.2
米扑代理支付方式:https://proxy.mimvp.com/buy.php
PayPal 在2018年7月发送的通知邮件,要求网站升级到 https SSL TLSv1.2
若网站不升级到 https SSL TLSv1.2 ,之前客户采用的 JDK 1.6、1.7(JDK1.8 默认支持 SSL TLSv1.2),或 PHP curl、以及shell 命令 curl https://proxy.mimvp.com 都可能出问题
Java 老版 JDK 1.6、1.7 的解决方案,请见米扑博客:解决JDK1.7、JDK1.6不支持 TLS1.2 问题
PHP 和 Shell curl 命令报错信息如下:
[06-08-2018 01:11:54] PayPal\Core\PayPalHttpConnection : INFO: POST https://api.paypal.com/v1/oauth2/token
[06-08-2018 01:11:56] : ERROR: exception 'PayPal\Exception\PayPalConnectionException' with message 'SSL connect error' in /usr/local/nginx/html/mimvp-proxy/paypal/lib/PayPal/Core/PayPalHttpConnection.php:140
本文主要介绍如何解决 PHP curl、Shell curl 命令支持 https SSL TLSv1.2
一、检测当前网站支持的协议
检测服务器网站SSL版本:https://www.howsmyssl.com/a/check
检测结果如下:
{
given_cipher_suites: [
"TLS_GREASE_IS_THE_WORD_BA",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_RSA_WITH_AES_128_GCM_SHA256",
"TLS_RSA_WITH_AES_256_GCM_SHA384",
"TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_RSA_WITH_AES_256_CBC_SHA",
"TLS_RSA_WITH_3DES_EDE_CBC_SHA"
],
ephemeral_keys_supported : true,
session_ticket_supported : true,
tls_compression_supported : false,
unknown_cipher_suite_supported : false,
beast_vuln : false,
able_to_detect_n_minus_one_splitting : false,
insecure_cipher_suites : { },
tls_version : "TLS 1.2",
rating : "Probably Okay"
}
上面的示例,检测的是网站(www.howsmyssl.com)的SSL信息
若想检测自己服务器网站的 SSL 信息,php 代码如下:
vim test_ssl.php
<?php $ch = curl_init('https://www.howsmyssl.com/a/check'); // 请求检测网址 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = curl_exec($ch); curl_close($ch); $json = json_decode($data); echo $json->tls_version; // 打印出 tls 版本信息 echo "<br><br>\n\n"; $curl_info = curl_version(); echo $curl_info['ssl_version']; // 打印出 curl 版本 ?>
运行结果:
TLS 1.0
NSS/3.27.1
可见,当前服务器网站只支持 TLS 1.0 版本,并不支持 TLS 1.2 版本,因此 curl、php curl 都无法访问
这里,进一步查看下 curl 、php、CentOS版本
# curl --version
curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz
# php --version
PHP 5.6.11 (cli) (built: Jan 31 2016 11:42:48)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
# lsb_release -a
LSB Version: :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS release 6.5 (Final)
Release: 6.5
Codename: Final
由上可见,curl 早期版本太低,在编译安装php时,无法编译支持 TLS1.2
为了进一步查看 php 编译安装时,所使用的 curl 版本,可以打印出 phpinfo(); 信息
上图可见,几年前安装的 CentOS、curl、php 等版本都偏低,导致 php 编译安装时使用的 curl 版本是 curl-7.19.7 太低了,不支持最新的安全标准 SSL TLSv1.2
二、升级 curl 版本,重新编译 php 到最新版 curl
因为 curl 版本太低,而 php 请求网页又用到了 curl ,因此要支持 SSL TLSv1.2 版本,需要升级 curl 版本
1、查看 curl 版本对 TLS 版本的支持
curl 官网查看:CURLOPT_SSLVERSION explained
CURLOPT_SSLVERSION - set preferred TLS/SSL version
Use one of the available defines for this purpose. The available options are:
CURL_SSLVERSION_DEFAULT
The default acceptable version range. The mimimum acceptable version is by default TLS 1.0 since 7.39.0 (unless the TLS library has a stricter rule).
CURL_SSLVERSION_TLSv1
TLS v1.0 or later
CURL_SSLVERSION_SSLv2
SSL v2 (but not SSLv3)
CURL_SSLVERSION_SSLv3
SSL v3 (but not SSLv2)
CURL_SSLVERSION_TLSv1_0
TLS v1.0 or later (Added in 7.34.0)
CURL_SSLVERSION_TLSv1_1
TLS v1.1 or later (Added in 7.34.0)
CURL_SSLVERSION_TLSv1_2
TLS v1.2 or later (Added in 7.34.0)
CURL_SSLVERSION_TLSv1_3
TLS v1.3 or later (Added in 7.52.0)
语法:
#include <curl/curl.h>
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSLVERSION, long version);
示例:
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2 );
curl_setopt($ch, CURLOPT_SSLVERSION, 6);
curl 官网下载:https://curl.haxx.se/download.html
curl 最新版本:curl-7.61.0.tar.gz (2018-07-11)
curl --tlsv1.0 https://www.xxx.com -v
# wget http://curl.haxx.se/download/curl-7.61.0.tar.gz
# tar -zxvf curl-7.35.0.tar.gz
# cd curl-7.35.0.tar.gz
#./configure --prefix=/usr/local/curl
# make
# make install
cd php-5.2.17
./configure --prefix=/alidata/server/php --with-config-file-path=/alidata/server/php/etc --with-mysql=/alidata/server/mysql --with-mysqli=/alidata/server/mysql/bin/mysql_config --with-pdo-mysql=/alidata/server/mysql/bin/mysql_config --enable-fpm --enable-fastcgi --enable-static --enable-maintainer-zts --enable-zend-multibyte --enable-sockets --enable-wddx --enable-zip --enable-calendar --enable-bcmath --enable-soap --with-zlib --with-iconv --with-gd --with-xmlrpc --enable-mbstring --without-sqlite --with-curl=/usr/local/curl/ --enable-ftp --with-mcrypt --with-freetype-dir=/usr/local/freetype.2.1.10 --with-jpeg-dir=/usr/local/jpeg.6 --with-png-dir=/usr/local/libpng.1.2.8 --disable-ipv6 --disable-debug --with-openssl
#make
make ZEND_EXTRA_LIBS='-liconv'
make install
cd ..
cp -f php-5.2.17.ini /alidata/server/php/etc/php.ini
cp -f php-fpm-5.2.17.conf /alidata/server/php/etc/php-fpm.conf
ln -s /alidata/server/php/sbin/php-fpm /etc/init.d/php-fpm
chmod 755 /alidata/server/php/sbin/php-fpm
/etc/init.d/php-fpm start
参考推荐:
PayPal PAY request returns SSL connect error (github)
Curl CURLOPT_SSLVERSION explained
PHP Curl (with NSS) is probably using SSLv3 insted of TLS when connecting to https
CURL ERROR: Recv failure: Connection reset by peer - PHP Curl
How do I list the SSL/TLS cipher suites a particular website offers
https://www.howsmyssl.com/s/api.html
TLS/SSL 协议详解 (28) TLS 1.0、TLS 1.1、TLS 1.2之间的区别
TLS/SSL 协议详解 (31)TLS1.1 TLS1.2 在CBC模式下两种不同的加解密方式及优化思考
版权所有: 本文系米扑博客原创、转载、摘录,或修订后发表,最后更新于 2019-01-15 05:15:56
侵权处理: 本个人博客,不盈利,若侵犯了您的作品权,请联系博主删除,莫恶意,索钱财,感谢!