米扑代理为了方便国外客户购买,支持 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

 

 

参考推荐

解决JDK1.7、JDK1.6不支持 TLS1.2 问题

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模式下两种不同的加解密方式及优化思考

Android HTTPS、TLS版本支持相关解决方案

https站点强制通信协议TLSv1.2

使用Charles进行https抓包