首页 > 解决方案 > 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 选项来解决这个问题?

标签: phpsslcurlopensslphp-curl

解决方案


我发现您可以将自定义 openssl 配置传递给 php cli,并为这个问题提出了一种可能的(丑陋的)解决方案:

  1. 在项目的某处创建一个单独的 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
  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);
  1. 现在调用此文件并通过以下方式在主代码中使用 php cli 传递自定义 openssl 配置shell_exec

$cmd = shell_exec("OPENSSL_CONF=openssl.cnf php example.php");

这样你就不需要为你的整个项目降低你的 openssl 版本/安全性,而只会在这个请求时降低它。卷曲文件可以修改为更加动态(自定义 url、查询参数、键等)。


推荐阅读