PHP cURL:强制实施低 TLS 版本
PHP cURL: enforce low TLS version
目标是为 TLS v1.2 连接编写 PHP 代码测试。获得成功的答案不是问题,但我无法通过在 PHP 中使用较旧的 TLS 版本来产生失败。显然需要测试失败来证明代码的正确性(在某种合理程度上)。
在命令行上我可以想出这个,给出一个明确的区别:
$ curl -X POST https://api.paypal.com/v1/oauth2/token
{"name":"AUTHENTICATION_FAILURE", [...]
$ curl --tls-max 1.1 -X POST https://api.paypal.com/v1/oauth2/token
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
在 PHP 我试过这个...
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.paypal.com/v1/oauth2/token');
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
// $response: '{"name":"AUTHENTICATION_FAILURE", [...]
... 这意味着成功的 TLS v1.2 连接,正如在上面的 CLI 示例中所见,尽管请求了 TLS v1.1。这与请求 CURL_SSLVERSION_TLSv1_2.
时的结果相同
这是带有 cURL 7.64.0 的 PHP 7.3.7,我希望我可以在不重新编译的情况下离开 PHP 只是为了禁用 TLS v1.2 支持。
小PHP/CURL测试脚本:
<?php
echo 'PHP version: ' . phpversion() . PHP_EOL;
echo 'cURL version: ' . curl_version()['version'] . PHP_EOL;
$ch = curl_init('https://www.howsmyssl.com/a/check');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0); // TLS 1.0
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1); // TLS 1.1
//curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); // TLS 1.2 or 1.3
$data = curl_exec($ch);
curl_close($ch);
$json = json_decode($data);
echo ($data ? $json->tls_version : 'curl request failed') . PHP_EOL;
"TLS v1.1 being requested" 是错误的,因为 TLS v1.1 或更高版本(在 7.34.0 中添加)非常清楚,"The maximum TLS version can be set by using one of the CURL_SSLVERSION_MAX_ macros"
要回答我自己的问题,文档位于 https://www.php.net/function.curl-setopt is/was outdated. cURL 7.54 changed behavior of CURL_SSLVERSION_ macros, these set now the minimum acceptable TLS version for the connection. It also introduced CURL_SSLVERSION_MAX_ macros, which set the maximum TLS version tried. Until PHP documentation is updated, see https://curl.haxx.se/libcurl/c/CURLOPT_SSLVERSION.html。
因此,限制与 TLS v1.1 的连接是这样的:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.paypal.com/v1/oauth2/token');
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
目标是为 TLS v1.2 连接编写 PHP 代码测试。获得成功的答案不是问题,但我无法通过在 PHP 中使用较旧的 TLS 版本来产生失败。显然需要测试失败来证明代码的正确性(在某种合理程度上)。
在命令行上我可以想出这个,给出一个明确的区别:
$ curl -X POST https://api.paypal.com/v1/oauth2/token
{"name":"AUTHENTICATION_FAILURE", [...]
$ curl --tls-max 1.1 -X POST https://api.paypal.com/v1/oauth2/token
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
在 PHP 我试过这个...
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.paypal.com/v1/oauth2/token');
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
// $response: '{"name":"AUTHENTICATION_FAILURE", [...]
... 这意味着成功的 TLS v1.2 连接,正如在上面的 CLI 示例中所见,尽管请求了 TLS v1.1。这与请求 CURL_SSLVERSION_TLSv1_2.
时的结果相同这是带有 cURL 7.64.0 的 PHP 7.3.7,我希望我可以在不重新编译的情况下离开 PHP 只是为了禁用 TLS v1.2 支持。
小PHP/CURL测试脚本:
<?php
echo 'PHP version: ' . phpversion() . PHP_EOL;
echo 'cURL version: ' . curl_version()['version'] . PHP_EOL;
$ch = curl_init('https://www.howsmyssl.com/a/check');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0); // TLS 1.0
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1); // TLS 1.1
//curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); // TLS 1.2 or 1.3
$data = curl_exec($ch);
curl_close($ch);
$json = json_decode($data);
echo ($data ? $json->tls_version : 'curl request failed') . PHP_EOL;
"TLS v1.1 being requested" 是错误的,因为 TLS v1.1 或更高版本(在 7.34.0 中添加)非常清楚,"The maximum TLS version can be set by using one of the CURL_SSLVERSION_MAX_ macros"
要回答我自己的问题,文档位于 https://www.php.net/function.curl-setopt is/was outdated. cURL 7.54 changed behavior of CURL_SSLVERSION_ macros, these set now the minimum acceptable TLS version for the connection. It also introduced CURL_SSLVERSION_MAX_ macros, which set the maximum TLS version tried. Until PHP documentation is updated, see https://curl.haxx.se/libcurl/c/CURLOPT_SSLVERSION.html。
因此,限制与 TLS v1.1 的连接是这样的:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.paypal.com/v1/oauth2/token');
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);