使用 PHP 中的 curl 连接到在证书包中显示过期根证书的站点

Posted

技术标签:

【中文标题】使用 PHP 中的 curl 连接到在证书包中显示过期根证书的站点【英文标题】:Connect to a site presenting an expired root certificate in the certificate bundle with curl in PHP 【发布时间】:2020-09-19 11:32:53 【问题描述】:

周末,Sectigo AddTrust External CA Root expired。对于现代浏览器,这对受影响网站的用户应该没有任何影响。

我们的 php 应用程序连接到一个我们无法控制的站点,该站点在其证书包中包含这个过期的根。我们使用 curl 连接,并验证证书。但是由于这个根现在已经过期,curl 现在拒绝连接,并出现证书过期的错误。

https://addtrustchain.test.certificatetest.com/ 有一个示例网站表现出相同的行为

表现出相同行为的示例代码是

$ch = curl_init();

$url = 'https://addtrustchain.test.certificatetest.com/';
//$url = 'https://google.com';
$caPath = '/path/to/cacert.pem';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch,CURLOPT_CAINFO, $caPath);

$output = curl_exec($ch);

var_dump($output);
var_dump(curl_getinfo($ch));
var_dump(curl_errno($ch));
var_dump(curl_error($ch));

curl_close($ch);

在 php 方面是否有一种解决方法,我们可以忽略捆绑包中提供的过期根证书?我们正在尝试与另一方合作,从他们的捆绑包中删除/更新过期的根目录,但如果下次出现这种情况,我们这边的解决方案会很棒。

我已尝试更新我们的本地 cacert.pem 以包含实际证书本身以及提供的中介,但这些似乎都不能解决问题。

【问题讨论】:

刚刚快速搜索并找到了agwa.name/blog/post/fixing_the_addtrust_root_expiration - 抱歉,不知道它是否有帮助,但可能有用。 谢谢。是的,这是同一个问题,但目前建议的修复方法似乎对我不起作用。 也相关:security.stackexchange.com/questions/232445/… 事实证明,虽然这在我的本地环境中对我不起作用,但对团队中的其他人确实有效,并且看起来在生产环境中也有效。干杯。 【参考方案1】:

您需要从您的 cacert.pem 中删除 AddTrust External Root

对于那些想知道的人,您可以从 Mozilla 那里获取 cacert.pem:https://curl.haxx.se/docs/caextract.html 然后你需要删除AddTrust External Root

删除AddTrust External Root 强制软件使用正确的路径认证(当您有多个时)。

例如,twinoid.com 有 3 个路径。其中两个是有效的,最后一个包含AddTrust External Root。 https://www.ssllabs.com/ssltest/analyze.html?d=twinoid.com&hideResults=on(可以查看那里的3条路径)

【讨论】:

谢谢。这在我的本地环境中对我不起作用,但对团队中的其他人确实有效,并且看起来它在生产环境中有效。干杯。

以上是关于使用 PHP 中的 curl 连接到在证书包中显示过期根证书的站点的主要内容,如果未能解决你的问题,请参考以下文章

cURL 和 PHP 显示“1”

如何创建允许 PHP 通过 SSL 连接到 MySQL 的证书?

如何使用 curl 和 php 连接到安全 (https) 代理?

带有 SSL 证书的 cURL 失败:错误 58 无法设置私钥文件

PHP Curl(带有 NSS)在连接到 https 时可能使用 SSLv3 而不是 TLS

使用带有 --ssl 的 PHP PDO 连接到 MySQL/MariaDB,无需证书