修复SSL证书问题:无法在PHP中获得本地颁发者证书



在我的PHP代码中,有时我会执行一个指向外部网站的cURL。今天,我突然出现了这个错误:

SSL证书问题:无法获取本地颁发者证书

这是我的代码的相关部分:

//downloaded from https://curl.haxx.se/docs/caextract.html
//(latest version Wed Oct 14 03:12:15 2020 GMT)    
$cacert_pem = realpath("some/path/to/cacert.pem"); 
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($query_data));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_CAINFO, $cacert_pem);

在网上搜索这个问题时,我遇到了很多来自这个网站的问题,但没有一个真正解释发生了什么,他们只是告诉编辑php.ini并指向cacert文件,或者将文件更新到新版本,或者做这样的事情:

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

这显然是不推荐的。。。

然后我降落在这里https://www.offset101.com/fix-ssl-certificate-problem/其中一个解决方案是:

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $cacert_pem);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $cacert_pem);

错误消失了!

所以,我的问题是:

  1. 为什么会发生这种情况?我的意思是,为什么代码昨天可以工作,但今天不行。如果我理解正确的话,问题就在我这边,而不是在外部网站上
  2. 所描述的解决方案是否真的解决了问题,还是与将值设置为0相同?根据文件https://www.php.net/manual/es/function.curl-setopt.php,则CURLOPT_SSL_VERIFYHOST的可能值为0、1或2
  3. 当然。。。我该怎么解决这个问题

为什么会发生这种情况?我的意思是,为什么代码昨天可以工作,但今天不行。如果我理解正确,问题就在我这边,而不是在外部网站上

如果不对代码进行任何更改,并且代码突然停止工作,则问题可能出在远程站点上。一个典型的问题是,站点的证书被续订,证书设置不正确(如缺少中间证书(,或者证书现在由不同的CA颁发。

由于您的CA信任存储看起来只是Firefox常用的信任存储,我认为问题是服务器端的配置错误。由于我们不知道您试图访问的网站,您必须亲自查看。为此,您可以使用SSLabs来分析网站,然后查找任何问题,特别是";链问题";。

所描述的解决方案是否真的解决了问题,或者与将值设置为0相同?

根据我的理解;解决方案";是危险的错误。正如您正确认识到的那样,这些选项不将字符串作为参数,而只将数字作为参数。给定一个字符串将隐式地将该字符串转换为一个数字,除非该字符串以数字开头,否则将导致0。因此在大多数情况下;"修复";你提到的帖子中显示的实际上禁用了证书验证。难怪这个错误会消失,但这当然是非常危险的。

当然。。。我该怎么解决这个问题?

取决于错误的实际原因。如果服务器中缺少中间证书,您可以尝试将这些丢失的证书添加到您的信任存储中,即添加到您已经存在的证书之外。

最新更新