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

Posted

技术标签:

【中文标题】PHP Curl(带有 NSS)在连接到 https 时可能使用 SSLv3 而不是 TLS【英文标题】:PHP Curl (with NSS) is probably using SSLv3 instead of TLS when connecting to https 【发布时间】:2014-12-14 16:10:58 【问题描述】:

我在 php 中使用 curl 库(带有 NSS)连接到我的其他服务器。一切都很好,直到上周,由于贵宾犬漏洞(顺便说一下 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,但我不能 100% 确定。我得到的只是“SSL 连接错误”,我不知道如何找出用于连接的 SSL 版本。

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

【问题讨论】:

“我无法更改任何 php.ini 配置或更新任何组件” - 但您的主机可以,并且或多或少有义务解决此类安全问题,因此您应该与他们交谈也。不久前我在 Java 中遇到了类似的问题,它默认使用 SSLv3 握手,即使它只被允许使用它协商 TLSv1+,并且我正在与之交谈的服务器即使在握手时也拒绝接受 SSLv3,所以这可能是问题在这里,但我不知道该怎么说对不起。 谢谢,我已经检查了这些组件(php、curl、NSS)的版本,并且所有这些组件都应该支持 TLS。它们并没有那么过时,所以我不知道,即使我说服我的主人这样做,更新是否会产生任何影响。 @Lapak 你明白了吗?我正在尝试使用 TLS 连接到服务器,因为它禁用了 SSL,它似乎不允许我这样做。 @TerisL 好吧,不是真的。问题出在 curl 版本中,就像下面提到的 Steffen。我试图说服我的主人更新 curl 库,但似乎他们不会这样做(令人惊讶的是......)。如果你需要简单的连接,你可以试试 fopen (php.vrana.cz/alternativa-ke-knihovne-curl.php (对不起捷克,但代码是不言自明的))。我实际上确实需要使用 curl,所以现在我正在尝试找到一种方法,如何不将 https 仅用于一个 IP,并使用其他一些方法来保护传输,而不使用 SSL。但这不是很好的解决方案。没有 curl 更新可能只有一个:( 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

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

(也在这里讨论过Update PHP cURL request from SSLv3 to TLS..?)。

正如有用的评论,这适用于 openssl curl 库,不适用于 nss

【讨论】:

我试过了,但这不是我的情况。此精确设置仅适用于 OpenSSL。对于 NSS,可以在此处找到密码列表:git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html 但没有一个 ECDHE 密码对我不起作用。如前所述,这很可能是由于我的主机具有的 curl/NNS 版本。感谢您的评价!【参考方案3】:

我有 Curl 7.21.7 和 PHP 5.4.34,这似乎对我有用:

curl_setopt($curl_request, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

更多信息here,虽然没有说明何时引入 CURL_SSLVERSION_TLSv1。

【讨论】:

谢谢,但这在我的设置中不起作用。我仍然收到错误“SSL 连接错误”。我也尝试过 CURL_SSLVERSION_TLSv1_0 等,但它们也没有按预期工作(因为它们是在更高版本中添加的)【参考方案4】:

这是一个有趣的问题。

如果您对该站点查询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,因此您的 curl 太旧,无法将必要的密码与 NSS 库一起使用。这意味着你需要升级你的 curl 库。

【讨论】:

我永远不会将所有这些联系在一起 :) 谢谢!我会试着让我的主人知道这一点。 这已成为一件大事,有如此多的服务提供商终止 SSL 并要求您切换到 TLS。我收到了来自工具用户的大量支持请求,他们的网络主机具有先前版本的 cURL 并且不愿意更新它(无论出于何种原因)。 当我在这里找到你的答案时,我以为我已经弄清楚了,但是现在我有运行 cURL 7.38.0 的人在我专门设置 TLSv1 时收到此错误:“列表中的未知密码:TLSv1 ”。无论他们的 cURL 版本如何,我应该如何让每个人都能使用它?现在很迷茫。 不幸的是,SSL 可能会出现很多问题,而且错误消息通常不会显示真正的问题。我建议这是一个不同的问题,所以最好开始一个新问题并提供尽可能多的信息。最好的办法是提供尽可能多的信息,以便人们可以重现问题,以便对其进行调试。 如果您发现自己遇到了与密码有关的重大兼容性问题,那么还有一个尚未完全破解的“旧”密码(但只是很弱)... 3DES...我'我们必须启用它以允许一些过时的客户端连接到事物......

以上是关于PHP Curl(带有 NSS)在连接到 https 时可能使用 SSLv3 而不是 TLS的主要内容,如果未能解决你的问题,请参考以下文章

Curl 失败:NSS:未找到客户端证书(未指定昵称)-在 Centos 7 上

PHP 在连接到 MySql 时忽略 ssl 证书

ModX/PHP:在连接到数据库的根目录中有我自己的文件吗?

使用通过 NSS 启用 curl 的 paypal 商家 sdk

在连接到上游客户端时负载平衡没有实时上游

cURL SSL连接错误35与NSS错误-5961