验证 curl 是否正在使用 TLS

Verify if curl is using TLS

在我的 PHP 应用程序中,我使用 PHP 的 CURL 和 openssl,使用 SOAP 进行连接和通话。 到目前为止,远程服务器支持 SSL 和 TLS,但由于 "poodle" 错误,管理员决定禁用 SSL 并仅使用 TLS。 SSL 支持到一月底。

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

curl_setopt($objCurl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);

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

但这只是理论 - 我需要验证它是否确实使用了 TLS - 有什么方法可以做到这一点吗? 有一个方法叫 curl_getinfo(),但是 returns 对我没用:

[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

非常感谢

简答

使用 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

使用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

如果您想测试特定 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