php - PHP curl 降低 SSL 安全性(ca md too weak 错误)
问题描述
我正在尝试使用我的证书和私钥通过 curl 发送简单的 GET 请求:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://example.com',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_SSLCERT => '/path_to/cert.pem',
CURLOPT_SSLKEY => '/path_to/key.pem',
));
curl_exec($curl);
$error = curl_error($curl);
curl_close($curl);
var_dump($error);
die();
终端中的等效命令是:
curl -GET --key key.pem --cert cert.pem https://example.com
运行这个 curl 我得到这个错误 -could not load PEM client certificate, OpenSSL error error:140AB18E:SSL routines:SSL_CTX_use_certificate:ca md too weak, (no key found, wrong pass phrase, or wrong file format?)
据我了解,这是因为我使用的证书是用 md5 哈希签名的。(如何修复 SSL 问题 SSL_CTX_use_certificate:ca md 在 Python Zeep 上太弱)
我无法重新创建这些密钥,所以我找到的解决方案是降低 ssl 安全级别(https://askubuntu.com/questions/1233186/ubuntu-20-04-how-to-set-lower-ssl-security -level),为此我需要编辑我的/etc/ssl/openssl.cnf
文件,特别是这部分 - CipherString = DEFAULT@SECLEVEL=1
(从 SECLEVEL=2 设置为 SECLEVEL=1)。
编辑完后openssl.cnf
,如果我在终端中运行我的 curl 命令 - 它可以工作。但是,如果我在 PHP 中运行它,问题仍然存在。
我尝试设置不同的 curl 选项,但似乎没有任何效果。这是我尝试过的 curl 选项:
CURLOPT_SSL_VERIFYHOST => false
CURLOPT_SSL_VERIFYPEER => false
CURLOPT_SSL_CIPHER_LIST => 'TLSv1'
CURLOPT_SSL_CIPHER_LIST => 'DEFAULT@SECLEVEL=1'
有没有办法在不编辑 openssl.cnf 文件的情况下通过设置一些 curl 选项来解决这个问题?
解决方案
我发现您可以将自定义 openssl 配置传递给 php cli,并为这个问题提出了一种可能的(丑陋的)解决方案:
- 在项目的某处创建一个单独的 openssl.cnf 文件,降低安全设置:
openssl_conf = default_conf [ default_conf ] ssl_conf = ssl_sect [ssl_sect] system_default = system_default_sect [system_default_sect] MinProtocol = TLSv1.2 CipherString = DEFAULT:@SECLEVEL=1
- 创建一个单独的 php example.php 文件,它将发出 curl 请求:
$curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'https://example.com', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_SSLCERT => 'cert.pem', CURLOPT_SSLKEY => 'key.pem', )); $response = curl_exec($curl); $error = curl_error($curl); curl_close($curl);
- 现在调用此文件并通过以下方式在主代码中使用 php cli 传递自定义 openssl 配置
shell_exec
:
$cmd = shell_exec("OPENSSL_CONF=openssl.cnf php example.php");
这样你就不需要为你的整个项目降低你的 openssl 版本/安全性,而只会在这个请求时降低它。卷曲文件可以修改为更加动态(自定义 url、查询参数、键等)。
推荐阅读
- c - 将文件名作为参数传递给 fopen() 不起作用
- javascript - 如何动态设置图形折线图?
- docker - 弹性容器服务上的“sh: 1: ./binary: Permission denied”
- swift - 如何快速加载标签每秒?
- html - 空值正在使用 express 返回数组
- stripe-payments - Stripe Payment Link 成功链接以包含会话 ID
- php - 我无法连接 mongdb 数据库(致命错误:未捕获的 MongoDB\Driver\Exception\ConnectionTimeoutException:无法查找 SRV 记录)
- python - 模板不存在 django
- reactjs - 将电子存储与反应一起使用
- java - Springboot Maven 中从未使用过的控制器类