验证 curl 是不是使用 TLS

Posted

技术标签:

【中文标题】验证 curl 是不是使用 TLS【英文标题】:Verify if curl is using TLS验证 curl 是否使用 TLS 【发布时间】:2015-03-10 09:19:23 【问题描述】:

在我的 php 应用程序中,我使用 PHP 的 CURL 和 openssl,通过 SOAP 进行连接和交谈。 到目前为止,远程服务器支持 SSL 和 TLS,但由于“贵宾犬”错误,管理员决定禁用 SSL 并仅使用 TLS。 支持 SSL 直到 1 月底。

我通过添加更改了我的代码:

curl_setopt($objCurl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);

理论上应该强制 curl 使用 TLSv1.2。

但这是理论上的——我需要验证它是否真的使用了 TLS——有什么方法可以做到吗? 有一个名为 curl_getinfo() 的方法,但它返回的信息对我没有用:

[url] => https://www.example.com/soap/MessagingPort
[content_type] => text/xml;charset=utf-8
[http_code] => 200
[header_size] => 293
[request_size] => 882
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.164487
[namelookup_time] => 3.4E-5
[connect_time] => 3.4E-5
[pretransfer_time] => 0.000122
[size_upload] => 604
[size_download] => 178
[speed_download] => 1082
[speed_upload] => 3672
[download_content_length] => 178
[upload_content_length] => 604
[starttransfer_time] => 0.164477
[redirect_time] => 0

提前致谢

【问题讨论】:

您可以使用某种网络嗅探器检查握手,或者如果可以的话,禁用服务器上的 SSL 和 TLS 1.0 和 1.1,以便它必须与 TLS 1.2 连接. 脚本在共享主机上工作,因此无法嗅探它。我已经强制我的开发服务器上的 Apache 使用 TLS 并且它可以工作,但我无法在生产中检查它。在使用 php 几年后,您开始不再认为一切都是理所当然的。我仍然需要一种方法来在屏幕上显示“您正在使用 TLS”。我的 Debian 上也有一个问题,没有定义 CURL_SSLVERSION_TLSv1_2,必须将行更改为: curl_setopt($objCurl, CURLOPT_SSLVERSION, 6); 【参考方案1】:

如果您想测试特定 url 使用的协议(如支付 api 端点),您可以log curl's verbose output 并在那里查看。这是一个简单的例子:

$url = 'https://example.com/';
$ch  = curl_init($url);
$out = fopen('php://temp', 'w+');

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $out);
curl_exec($ch);
curl_close($ch);
rewind($out);

$debug = stream_get_contents($out);

if (preg_match('/SSL connection.*/', $debug, $match)) 
    echo '<pre>' . $url . PHP_EOL . $match[0];

对我来说,输出如下:

https://example.com/
SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384

【讨论】:

【参考方案2】:

使用https://tlstest.paypal.com:

例如:

$ curl https://tlstest.paypal.com/
ERROR! Connection is using TLS version lesser than 1.2. Please use TLS1.2

$ ./src/curl https://tlstest.paypal.com/
PayPal_Connection_OK

【讨论】:

【参考方案3】:

简答

使用 curl 向https://www.howsmyssl.com/ 发出请求

<?php 
$ch = curl_init('https://www.howsmyssl.com/a/check');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);

$json = json_decode($data);
echo $json->tls_version;

应该输出用于连接的 TLS 版本。

深入挖掘

Curl 依赖于底层的 OpenSSL(或 NSS)库来进行安全连接的协商。所以我相信这里要问的正确问题是 OpenSSL 库有什么能力。如果它可以处理 TLS 连接,那么 curl 可以处理 TLS 连接。

那么如何弄清楚 openssl(或 NSS)库的功能呢?

<?php    
$curl_info = curl_version();
echo $curl_info['ssl_version'];

这将倾倒出类似的东西

OpenSSL/1.0.1k

然后您可以查看该版本的发行说明,看看它是否包含 TLS 支持。

OpenSSL 发行说明 - https://www.openssl.org/news/changelog.html

NSS 发行说明 - https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_Releases

剧透警告

openssl 在 OpenSSL 1.0.1 中包括对 TLS v1.1 和 TLS v1.2 的支持 [2012 年 3 月 14 日] NSS 在 3.14 中包含对 TLS v1.1 的支持 包括 NSS 在 3.15 中支持 TLS v1.2

【讨论】:

我对 howsmyssl 做了卷曲,它返回 error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version。它拒绝 ssl v2/3? twitter.com/jmhodges/status/420614636606468096。在这种情况下我该怎么办? 使用第二个 php 逻辑,我的服务器指示“NSS/3.19.1 Basic ECC”,这意味着支持 TLS v1.2,但是第一个 php 逻辑返回“TLS 1.0”?我需要做什么来支持 TLS 1.2? 别在意我之前的评论...我只是在 php 逻辑 #1 中添加了以下代码,现在我得到了 TLS 1.2 curl_setopt($ch, CURLOPT_SSLVERSION, 6); 可能需要添加curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cert/file/cacert.pem'); ref ***.com/questions/9774349/… 我收到了这样的错误:SSL certificate problem: unable to get local issuer certificatecurl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 已修复(临时)

以上是关于验证 curl 是不是使用 TLS的主要内容,如果未能解决你的问题,请参考以下文章

PayPal TLS 测试 URL - PHP curl SSL 协议错误

修改 PHP 代码以使用 TLS 而不是 SSL

TLS 1.2 在 cURL 中不起作用

cURL无法访问TLS网站故障解决

curl:如何在 Windows 上使用 Kerberos 而不是 NTLM 身份验证?

使用 AWS API Gateway 进行客户端 TLS 身份验证