PHP Curl(带 NSS)在连接到 https 时可能使用 SSLv3 而不是 TLS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26452755/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP Curl (with NSS) is probably using SSLv3 instead of TLS when connecting to https
提问by Lapak
I'm using curl library (with NSS) in PHP to connect to my other server. Everything was fine until last week, when the destination server stoped supporting SSLv3 due to poodle vulnerability (CloudFlare by the way). Now, I'm trying to make connection using TLS, but I'm still getting "SSL connect error".
我在 PHP 中使用 curl 库(带有 NSS)连接到我的其他服务器。一切都很好,直到上周目标服务器由于贵宾犬漏洞(顺便说一下 CloudFlare)而停止支持 SSLv3。现在,我正在尝试使用 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_SSLVERSION
为1
应该通过 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. All I have is phpinfo(). I've checked for TLS support on these components version and it should be fine. Here is excerpt of phpinfo:
我在共享主机提供商处拥有所有这些,因此我无法更改任何 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
I think, that problem is usage of SSLv3 instead of TLS, but I'm not 100% sure. All I'm getting is "SSL connect error" and I don't know, how to find out, which SSL version was used to connect.
我认为,这个问题是使用 SSLv3 而不是 TLS,但我不是 100% 确定。我得到的只是“SSL 连接错误”,我不知道如何找出用于连接的 SSL 版本。
Is there a way, how to check, which SSL version is used for connection? Or am I missing something?
有没有办法,如何检查,哪个 SSL 版本用于连接?或者我错过了什么?
回答by Steffen Ullrich
That's an interesting problem.
这是一个有趣的问题。
If you query SSLLabsfor this site you will see, that it only supports various ECDHE-ECDSA-* ciphers and no other ciphers. But, in the version history of curlyou 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".
如果您查询此站点的SSLLabs,您将看到,它仅支持各种 ECDHE-ECDSA-* 密码,不支持其他密码。但是,在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. This means you need to upgrade your curl library.
由于您使用的是 curl 7.19.7,因此您的 curl 太旧,无法将必要的密码与 NSS 库一起使用。这意味着您需要升级 curl 库。
回答by Derrick Miller
I have Curl 7.21.7 and PHP 5.4.34, and this seemedto do the trick for me:
我有 Curl 7.21.7 和 PHP 5.4.34,这似乎对我有用:
curl_setopt($curl_request, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
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 何时被引入。
回答by David Breise
The answer for me was to use an integer value instead of a string.. i.e.: 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
回答by philippe lhardy
Duplicate answer SSL error can not change to TLSproposed :
Duplicate answer SSL error can not change to 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 ).
(并在此处讨论Update PHP cURL request from SSLv3 to TLS ..?too )。
As usefully commented, this apply to opensslcurl library, not to nss.
正如有用的评论,这适用于opensslcurl 库,而不是nss。