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

12

我正在使用PHP中的curl库(带有NSS)连接到我的其他服务器。一切都很顺利,直到上周目标服务器由于poodle漏洞停止支持SSLv3(顺便说一下,是CloudFlare)。现在,我正在尝试使用TLS进行连接,但仍然出现“SSL连接错误”。

这是我使用的示例代码:

$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);
根据我的理解,将CURLOPT_SSLVERSION设置为1应该可以强制使用TLS连接。
注意:我设置CURLOPT_SSL_VERIFYPEER => false只是为了调试,不打算让它保留,一旦我解决了这个问题就会去掉它。
这是输出内容:
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

我将所有东西放在共享托管提供商上,所以我无法更改任何php.ini配置或更新任何组件。我只有phpinfo()。

我已经检查了这些组件版本的TLS支持情况,应该是可以的。以下是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

我认为问题在于使用了SSLv3而不是TLS,但我并不100%确定。我只得到了“SSL连接错误”的信息,我不知道如何找出连接使用了哪个SSL版本。

有没有一种方法可以检查连接使用的SSL版本?还是我漏掉了什么?


我无法更改任何php.ini配置或更新任何组件,但是您的主机可以,并且在像这样的安全问题上更或多或少地有义务这样做,因此您也应该与他们交谈。 我以前在Java中遇到过类似的问题,其中它默认使用SSLv3握手,即使只允许它协商TLSv1+,我正在与之通信的服务器拒绝接受SSLv3甚至用于握手,所以这可能是问题所在,但很抱歉我不知道如何告诉您。 - Rup
谢谢,我已经检查了这些组件(php、curl、NSS)的版本,并且它们都应该支持TLS。它们并不是那么过时,所以我不知道,即使我说服我的主机进行更新,是否会有任何区别。 - Lapak
@Lapak,你解决了这个问题吗?我正在尝试使用TLS连接到服务器,因为它禁用了SSL,但似乎无法让我连接成功。 - LefterisL
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Lapak
4个回答

21

这是一个有趣的问题。

如果你查询SSLLabs这个网站,你会发现它只支持各种ECDHE-ECDSA-* 算法,而没有其他算法。但是,在curl版本历史记录中,你会发现一个关于ECC算法和NSS库(你使用的库)的错误,该错误仅在curl 7.36版本中得到修复。“nss:允许使用ECC密码套件(如果NSS实现它们)”

由于你使用的是curl 7.19.7版本,因此你的curl版本太旧,无法与NSS库一起使用必要的密码套件。这意味着你需要升级你的curl库。


1
我从来不会把所有这些东西连接在一起 :) 谢谢!我会尝试向我的主机提出疑问。 - Lapak
这已经成为一个大问题,因为许多服务提供商正在停用SSL并要求您切换到TLS。我收到了很多支持请求,来自使用工具的用户,他们的Web主机有较早版本的cURL,并且不愿意更新它(出于任何原因)。 - Drew Angell
我以为在这里找到你的答案后就已经解决了这个问题,但现在当我特别设置TLSv1时,使用cURL 7.38.0的人们却遇到了“列表中的未知密码:TLSv1”错误。我应该如何让每个人都能够使用,而不受他们cURL版本的影响?现在非常困惑。 - Drew Angell
不幸的是,SSL 可能会出现很多问题,而且错误消息通常无法显示真正的问题。我建议这是一个不同的问题,最好开一个新的问题,并提供尽可能多的信息。最好的方法是提供足够的信息以便能够重现问题,以便进行调试。 - Steffen Ullrich
如果你发现自己在使用密码方面遇到了严重的兼容性问题,那么还有一种“旧”的密码算法仍然没有被完全破解(但是它相对较弱)... 3DES... 我不得不启用它来让一些过时的客户端连接到某些东西... - Brian Knoblauch
@BrianKnoblauch:请阅读答案:“……只支持各种ECDHE-ECDSA-密码和其他密码都不支持”,问题在于这个curl版本不支持任何一个*。这意味着你的建议在这种情况下没有帮助。 - Steffen Ullrich

13

我有Curl 7.21.7和PHP 5.4.34,似乎这可以解决我的问题:

curl_setopt($curl_request, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

更多信息请参见此处,虽然它没有说明CURL_SSLVERSION_TLSv1是何时引入的。


谢谢,但这在我的设置中不起作用。我仍然收到“SSL连接错误”的错误。我也尝试了CURL_SSLVERSION_TLSv1_0等等,但它们也不起作用,正如预期的那样(因为它们是在后来的版本中添加的)。 - Lapak

5
我的答案是使用整数值而不是字符串,即: 更改为:
curl_setopt($ch, CURLOPT_SSLVERSION_TLSv1_2);

To:

curl_setopt($ch, CURLOPT_SSLVERSION, 6);

或者选择tlsv1_1:

curl_setopt($ch, CURLOPT_SSLVERSION, 5);

以下是完整列表:

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)

顺便提一下,我正在运行以下内容:

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

3

我已经尝试过了,但这不适用于我的情况。这个确切的设置只适用于OpenSSL。对于NSS,可以在此处找到密码列表:https://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html,但是其中没有任何ECDHE密码适用于我。正如之前提到的,这很可能是由于我的主机使用的curl/NNS版本问题。感谢您的审阅! - Lapak

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