简体   繁体   English

当连接到https时,PHP Curl(使用NSS)可能使用SSLv3而不是TLS

[英]PHP Curl (with NSS) is probably using SSLv3 instead of TLS when connecting to https

I'm using curl library (with NSS) in PHP to connect to my other server. 我在PHP中使用curl库(使用NSS)连接到我的其他服务器。 Everything was fine until last week, when the destination server stoped supporting SSLv3 due to poodle vulnerability (CloudFlare by the way). 直到上周,由于poodle漏洞(顺便说一下CloudFlare),目标服务器停止支持SSLv3,一切都很好。 Now, I'm trying to make connection using TLS, but I'm still getting "SSL connect error". 现在,我正在尝试使用TLS建立连接,但我仍然遇到“SSL连接错误”。

There is sample code, I'm using: 有一些示例代码,我正在使用:

$ch = curl_init();
curl_setopt_array( $ch, array(
    CURLOPT_URL => 'https://www.lumiart.cz',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSLVERSION => 1,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_VERBOSE => true
) );
$output = curl_exec( $ch );
echo $output;

print_r( curl_getinfo( $ch ) );

echo 'error:' . curl_error( $ch );

curl_close($ch);

From my understanding, setting CURLOPT_SSLVERSION to 1 should force connection via TLS. 根据我的理解,将CURLOPT_SSLVERSION1应强制通过TLS连接。

Note: I have CURLOPT_SSL_VERIFYPEER => false just for debuging and I'm not meaning to leave it there, once I figure this problem out. 注意:我有CURLOPT_SSL_VERIFYPEER => false只是为了进行调试,一旦我解决了这个问题,我就没有意思将它留在那里。

This is output: 这是输出:

Array
(
    [url] => https://www.lumiart.cz
    [content_type] => 
    [http_code] => 0
    [header_size] => 0
    [request_size] => 0
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0
    [namelookup_time] => 2.3E-5
    [connect_time] => 0.005777
    [pretransfer_time] => 0
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => -1
    [upload_content_length] => -1
    [starttransfer_time] => 0
    [redirect_time] => 0
    [certinfo] => Array
        (
        )

    [primary_ip] => 2400:cb00:2048:1::681c:86f
    [redirect_url] => 
)
error:SSL connect error

I have all of this at shared hosting provider, so I can't change any php.ini configuration or update any components. 我在共享主机提供商处拥有所有这些,因此我无法更改任何php.ini配置或更新任何组件。 All I have is phpinfo(). 我所拥有的只是phpinfo()。 I've checked for TLS support on these components version and it should be fine. 我检查了这些组件版本的TLS支持,它应该没问题。 Here is excerpt of phpinfo: 这是phpinfo的摘录:

PHP Version 5.4.32
System  Linux wl42-f262 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64

curl:
cURL support    enabled
cURL Information    7.19.7
Age 3
Features
AsynchDNS   No
Debug   No
GSS-Negotiate   Yes
IDN Yes
IPv6    Yes
Largefile   Yes
NTLM    Yes
SPNEGO  No
SSL Yes
SSPI    No
krb4    No
libz    Yes
CharConv    No
Protocols   tftp, ftp, telnet, dict, ldap, ldaps, http, file, https, ftps, scp, sftp
Host    x86_64-redhat-linux-gnu
SSL Version NSS/3.15.3
ZLib Version    1.2.3
libSSH Version  libssh2/1.4.2

I think, that problem is usage of SSLv3 instead of TLS, but I'm not 100% sure. 我认为,问题是使用SSLv3而不是TLS,但我不是百分百肯定。 All I'm getting is "SSL connect error" and I don't know, how to find out, which SSL version was used to connect. 所有我得到的是“SSL连接错误”,我不知道,如何找出,用于连接的SSL版本。

Is there a way, how to check, which SSL version is used for connection? 有没有办法,如何检查,哪个SSL版本用于连接? Or am I missing something? 或者我错过了什么?

That's an interesting problem. 这是一个有趣的问题。

If you query SSLLabs for this site you will see, that it only supports various ECDHE-ECDSA-* ciphers and no other ciphers. 如果您查询此站点的SSLLabs ,您将看到它只支持各种ECDHE-ECDSA- *密码而不支持其他密码。 But, in the version history of curl you will find a bug with ECC ciphers and the NSS library (which you use) which is only fixed in curl version 7.36 "nss: allow to use ECC ciphers if NSS implements them" . 但是,在curl版本历史中,你会发现ECC密码和NSS库(你使用的)的一个错误,它只在curl版本7.36 “nss中修复:如果NSS实现它们,允许使用ECC密码”

Since you are using curl 7.19.7 your curl is too old to use the necessary ciphers together with the NSS library. 由于您使用的是curl 7.19.7,因此您的卷曲太旧而无法与NSS库一起使用必要的密码。 This means you need to upgrade your curl library. 这意味着您需要升级curl库。

I have Curl 7.21.7 and PHP 5.4.34, and this seemed to do the trick for me: 我有Curl 7.21.7和PHP 5.4.34,这似乎对我有用:

curl_setopt($curl_request, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

More info here , although it doesn't say when CURL_SSLVERSION_TLSv1 was introduced. 这里有更多信息,虽然它没有说明什么时候引入了CURL_SSLVERSION_TLSv1。

The answer for me was to use an integer value instead of a string.. ie: Change: 我的答案是使用整数值而不是字符串..即:更改:

curl_setopt($ch, CURLOPT_SSLVERSION_TLSv1_2);

To: 至:

curl_setopt($ch, CURLOPT_SSLVERSION, 6);

Or for tlsv1_1: 或者对于tlsv1_1:

curl_setopt($ch, CURLOPT_SSLVERSION, 5);

Here's the full list: 这是完整列表:

CURL_SSLVERSION_DEFAULT (0)
CURL_SSLVERSION_TLSv1 (1)
CURL_SSLVERSION_SSLv2 (2)
CURL_SSLVERSION_SSLv3 (3)
CURL_SSLVERSION_TLSv1_0 (4)
CURL_SSLVERSION_TLSv1_1 (5)
CURL_SSLVERSION_TLSv1_2 (6)

I'm running the following by the way: 顺便说一句,我正在运行以下内容:

curl-7.19.7-46.el6.x86_64
nss-3.21.0-0.3.el6_7.x86_64

Duplicate answer SSL error can not change to TLS proposed : 重复答案SSL错误无法更改为建议的TLS

Try adding CURLOPT_SSL_CIPHER_LIST => 'TLSv1' to your PPHttpConfig.php. 尝试将CURLOPT_SSL_CIPHER_LIST =>'TLSv1'添加到PPHttpConfig.php。

( and discussed here Update PHP cURL request from SSLv3 to TLS..? too ). (并在此处讨论将SSL cURL请求从SSLv3更新到TLS ..? )。

As usefully commented, this apply to openssl curl library, not to nss . 有用的评论,这适用于openssl curl库,而不是nss

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM