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

时间:2014-10-19 16:35:45

标签: php ssl curl https nss

我在PHP中使用curl库(使用NSS)连接到我的其他服务器。直到上周,由于poodle漏洞(顺便说一下CloudFlare),目标服务器停止支持SSLv3,一切都很好。现在,我正在尝试使用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,但我不是百分百肯定。我所说的只是“SSL连接错误”,我不知道如何找出使用哪个SSL版本进行连接。

有没有办法,如何检查,哪个SSL版本用于连接?或者我错过了什么?

感谢您的任何建议!

4 个答案:

答案 0 :(得分:20)

这是一个有趣的问题。

如果您查询此站点的SSLLabs,您会看到它只支持各种ECDHE-ECDSA- *密码而不支持其他密码。但是,在version history of curl中,您会发现ECC密码和NSS库(您使用的)的错误,该错误仅在curl版本7.36 "nss: allow to use ECC ciphers if NSS implements them"中修复。

由于您使用的是curl 7.19.7,因此您的卷曲太旧而无法与NSS库一起使用必要的密码。这意味着您需要升级curl库。

答案 1 :(得分:12)

我有Curl 7.21.7和PHP 5.4.34,这个似乎为我做了诀窍:

curl_setopt($curl_request, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

更多信息here,虽然它没有说明什么时候引入了CURL_SSLVERSION_TLSv1。

答案 2 :(得分:2)

建议重复的答案SSL error can not change to TLS

尝试添加CURLOPT_SSL_CIPHER_LIST => 'TLSv1'到你的PPHttpConfig.php。

(此处也讨论Update PHP cURL request from SSLv3 to TLS..?)。

如有用的评论,这适用于 openssl 卷曲库,而不适用于 nss

答案 3 :(得分:2)

我的答案是使用整数值而不是字符串.. ...: 变化:

curl_setopt($ch, CURLOPT_SSLVERSION_TLSv1_2);

要:

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