PHP - SSL 证书错误:无法获取本地颁发者证书
Posted
技术标签:
【中文标题】PHP - SSL 证书错误:无法获取本地颁发者证书【英文标题】:PHP - SSL certificate error: unable to get local issuer certificate 【发布时间】:2020-06-27 12:49:02 【问题描述】:我在 Windows 7 上运行 php 5.6.3 作为 XAMPP 的一部分。
当我尝试使用 Mandrill API 时,我收到以下错误:
未捕获的异常“Mandrill_HttpError”与消息“API 调用消息/发送模板失败:SSL 证书问题:无法获取本地颁发者证书”
我已经尝试了我在 *** 上阅读的所有内容,包括将以下内容添加到 php.ini 文件中:
curl.cainfo = "C:\xampp\php\cacert.pem"
当然还有从http://curl.haxx.se/docs/caextract.html下载cacert.pem文件到那个位置
但毕竟,重新启动了 XAMPP 和 Apache 服务器,但仍然出现相同的错误。
我真的不知道还能尝试什么。
谁能建议我还能尝试什么?
【问题讨论】:
查看我的回答:***.com/a/29649024/660410 还要确保您已通过删除开始的“;”取消注释该行。它应该是 curl.cainfo = "C:\xampp\php\cacert.pem" 而不是 ;curl.cainfo = "C:\xampp\php\cacert.pem" 是否使用 HTTPS over HTTP 也会导致此错误? 【参考方案1】:我发现新的解决方案不需要任何认证来调用 curl 只需添加两行代码。
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
【讨论】:
虽然这可能有效,但根本不建议这样做。您基本上是在说,信任所有证书...如果您忘记了并且您的代码通过此更改使其投入生产,它还会打开您的应用程序以应对可能的攻击...下载 CA 捆绑包和添加点 PHP 到它。 这是 curl 的概念,所以当你使用 curl 时,添加上面的代码 这种方案会导致中间人攻击,不推荐使用。【参考方案2】:我有这个问题的非常简单的解决方案。您可以在没有任何证书文件的情况下执行此操作。
请注意,此解决方案适用于本地系统而非客户端服务器和生产服务器。
继续 Laravel 根文件夹 -> Vender -> guzzlehttp -> guzzle -> src
打开Client.php
找到 $defaults 数组。看起来像这样..
$defaults = [
'allow_redirects' => RedirectMiddleware::$defaultSettings,
'http_errors' => true,
'decode_content' => true,
'verify' => true,
'cookies' => false
];
现在的主要工作是改变 verify 键的值..
'verify' => false,
因此,在此之后,它不会检查 SSL 证书以获取 CURL 请求...此解决方案对我有用。经过多次研究,我找到了这个解决方案......
【讨论】:
【参考方案3】:编者注:禁用 SSL 验证具有安全隐患。如果不验证 SSL/HTTPS 连接的真实性,恶意攻击者可以冒充一个受信任的端点(例如 GitHub 或其他一些远程 Git 主机),您将容易受到 Man-in-the-Middle Attack 的攻击。
在将其用作解决方案之前,请确保您完全了解安全问题。
这个我试过了
打开
vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php
然后改变这个
$conf[CURLOPT_SSL_VERIFYHOST] = 2;
`enter code here`$conf[CURLOPT_SSL_VERIFYPEER] = true;
到这里
$conf[CURLOPT_SSL_VERIFYHOST] = 0;
$conf[CURLOPT_SSL_VERIFYPEER] = FALSE;
【讨论】:
如果有什么比编辑vendor
目录中的文件更愚蠢的事情,那就是不验证 TLS 主机证书。【参考方案4】:
编者注:禁用 SSL 验证具有安全隐患。如果不验证 SSL/HTTPS 连接的真实性,恶意攻击者可以冒充一个受信任的端点(例如 GitHub 或其他一些远程 Git 主机),您将容易受到 Man-in-the-Middle Attack 的攻击。
在将其用作解决方案之前,请确保您完全了解安全问题。
我在 Mandrill.php 文件的第 65 行之后遇到了同样的问题,它说 $this->ch = curl_init();
添加以下两行:
curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
这解决了我的问题,还使用 localhost 发送了电子邮件,但我建议不要在实时版本中使用它。在您的实时服务器上,该代码应该可以在没有此代码的情况下工作。
【讨论】:
我可以尝试做些什么来让我的开发人员环境在没有这种绕过的情况下正常工作? 对我来说,只需将CURLOPT_SSL_VERIFYPEER
设置为 false
即可。
虽然您在技术上是正确的,但禁用 SSL 是个坏主意。即使在本地主机上,最好按照其他答案中的说明正确加载证书。
虽然您在技术上是正确的,但禁用 SSL 是个坏主意。即使它强烈反对以任何其他方式工作,最好还是丢掉工作而不是用不正确的系统管理员方式做事。 @脊柱
我对“你的服务器不安全”感到困惑,如果我用这个 sn-p ping 一个外部 API,它会让我的客户端不安全吗?【参考方案5】:
在 Amazon Linux(CentOS / Red Hat 等)上,我执行了以下操作来解决此问题。先把http://curl.haxx.se/ca/cacert.pem下载的cacert.pem复制下来,放到/etc/pki/ca-trust/source/anchors/
目录下。然后运行update-ca-trust
命令。
这是取自https://serverfault.com/questions/394815/how-to-update-curl-ca-bundle-on-redhat的单行代码
curl https://curl.se/ca/cacert.pem -o /etc/pki/ca-trust/source/anchors/curl-cacert-updated.pem && update-ca-trust
但是自从 curl 被破坏后,我实际上使用这个命令来下载 cacert.pem 文件。
wget --no-check-certificate http://curl.haxx.se/ca/cacert.pem
运行update-ca-trust
命令后,您可以重新启动 Web 服务器 service httpd restart
用于 apache 或 service nginx restart
用于 nginx。
【讨论】:
【参考方案6】:发生此错误的另一个原因是,如果 CA 捆绑包已从您的系统中删除(并且不再在 ca 证书中可用)。
GeoTrust Global CA 目前就是这种情况,它(除其他外)用于签署 Apple 的用于推送通知的 APNS 证书。
可以在此处的错误报告中找到更多详细信息:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=962596
您可以按照 Carlos Alberto Lopez Perez 的建议在您的计算机上手动添加 GeoTrust Global CA 证书:
wget --no-check-certificate -c https://www.geotrust.com/resources/root_certificates/certificates/GeoTrust_Global_CA.pem \
&& mkdir /usr/local/share/ca-certificates/extra \
&& mv GeoTrust_Global_CA.pem /usr/local/share/ca-certificates/extra/GeoTrust_Global_CA.crt \
&& update-ca-certificates
【讨论】:
【参考方案7】:我对这个问题有一个适当的解决方案,让我们尝试了解这个问题的根本原因。当无法使用系统证书存储中的根证书验证远程服务器 ssl 或远程 ssl 未与链证书一起安装时,就会出现此问题。如果您有一个具有 root ssh 访问权限的 linux 系统,那么在这种情况下,您可以尝试使用以下命令更新您的证书存储:
update-ca-certificates
如果还是不行,那么您需要在您的证书存储中添加远程服务器的根证书和临时证书。您可以下载根证书和中间证书并将它们添加到 /usr/local/share/ca-certificates 目录中,然后运行命令 update-ca-certificates
.这应该可以解决问题。同样,对于 Windows,您可以搜索如何添加根证书和中间证书。
解决此问题的另一种方法是要求远程服务器团队将 ssl 证书添加为域根证书、中间证书和根证书的捆绑包。
【讨论】:
【参考方案8】:我在我的本地系统中遇到了这样的问题,但在实时服务器中却没有。我之前也提到过这个页面上的另一个解决方案,但它在 localhost 中不起作用。所以找到一个新的解决方案,它在 localhost-WAMP 服务器 中起作用.
cURL 错误 #:SSL 证书问题:无法获取本地颁发者 证书
有时系统无法在您的驱动器中找到您的 cacert.pem。所以你可以在你要使用 CURL
的代码中定义它请注意,我正在满足所有条件,例如 OPEN-SSL 库活动和其他条件。
检查 CURL 的这段代码。
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL =>$url,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER=> true,
));
curl_setopt($curl, CURLOPT_CAINFO, "f:/wamp/bin/cacert.pem"); // <------
curl_setopt($curl, CURLOPT_CAPATH, "f:/wamp/bin/cacert.pem"); // <------
$response = json_decode(curl_exec($curl),true);
$err = curl_error($curl);
curl_close($curl);
但此解决方案可能不适用于实时服务器。因为 cacert.pem
的绝对路径【讨论】:
【参考方案9】:我收到如下错误:
failed loading cafile stream: `C:\xamppPhp\apache\bin\curl-ca-bundle.crt`
我正在使用 Windows 机器。所以我按照以下步骤操作。
1. I have downloaded .pem file from " https://curl.haxx.se/docs/caextract.html "
2. Then I kept the downloaded file inside "C:/xamppPhp/apache/bin/" folder and renamed the same downloaded file to "curl-ca-bundle.crt".
3. I restarted XAMPP and cleared the cache.
4. It's done.
希望对大家有所帮助
【讨论】:
【参考方案10】:你可以试试这个:
$client = new Client(env('API_HOST'));
$client->setSslVerification(false);
在 guzzle/guzzle 3 上测试。*
【讨论】:
回答一个已有 3 年历史且获得 200 多票赞成的答案是否有意义? 我的回答比上面的简单,你会看到我会在几个月内获得 10 次投票... 我非常怀疑,在 OP 中没有看到任何关于 guzzle 的提及......所以这是一个不相关的答案。当有人为 javascript 问题提供 jQuery 解决方案时也是如此。这无关紧要。 这并没有改变它没有在这里使用的事实。你会向 Windows 用户推荐一个 Linux 解决方案,因为它是最常用的服务器操作系统吗?不是每个人都想使用 Guzzle,在我使用 PHP 的这些年里,我个人从未使用过一次。对我来说,一个 HTTP 请求真的没有那么难,需要一个包。 完全意识到 - 它只是不需要.. 只需阅读 curl 的文档,这一切都是不言自明的。这不是要变得更聪明……而是要正确回答问题【参考方案11】:如果您无权访问 php.ini,添加此代码(在您的 $ch = curl_init();
行之后)对我有用:
$certificate_location = "C:\Program Files (x86)\EasyPHP-Devserver-16.1\ca-bundle.crt"; // modify this line accordingly (may need to be absolute)
curl_setopt($ch, CURLOPT_CAINFO, $certificate_location);
curl_setopt($ch, CURLOPT_CAPATH, $certificate_location);
然后,您只需下载ca-bundle.crt 并将其保存到您在$certificate_location
中指定的位置。
【讨论】:
【参考方案12】:终于搞定了!
下载certificate bundle。
把它放在某个地方。就我而言,那是 c:\wamp\
目录(如果您使用的是 Wamp 64 位,那么它是 c:\wamp64\
)。
在 Apache 中启用 mod_ssl
,在 php.ini
中启用 php_openssl.dll
(通过删除开头的 ;
取消注释它们)。但要小心,我的问题是我有两个 php.ini
文件,我需要在这两个文件中都这样做。一个是您从 WAMP 任务栏图标获得的,另一个是,在我的情况下,在 C:\wamp\bin\php\php5.5.12\
将这些行添加到 php.ini
文件中的证书中:
curl.cainfo="C:/wamp/cacert.pem"
openssl.cafile="C:/wamp/cacert.pem"
重启 Wamp 服务。
【讨论】:
在我的例子中是 c:\xamp\ 目录和它的 windows 7,这个解决方案很完美......非常感谢...... 最新的证书包可以从原curl站点curl.haxx.se/docs/caextract.html下载 在我的情况下,该行的开头有一个;
,我花了几个小时才意识到这意味着它是一个评论。所以对于像我这样的菜鸟,也需要删除;
@SurajNeupane 不确定,当时我花了很多时间才得到这个,我使用虚拟机,比如 Homestead,我不需要处理这个。这是特定情况
这是关键But be careful, my problem was that I had two php.ini files and I need to do this in both of them. One is the one you get from your WAMP taskbar icon, and another one is, in my case, in C:\wamp\bin\php\php5.5.12\
【参考方案13】:
详细说明上述服务器部署的答案。
$hostname = gethostname();
if($hostname=="mydevpc")
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
应该在不影响部署时影响服务器的情况下为开发环境解决问题。
【讨论】:
在不同的环境中运行代码的不同部分听起来不是一个好概念——它使调试变得更加困难【参考方案14】:感谢@Mladen Janjetovic,
您的建议在安装了 ampps 的 mac 中对我有用。
已复制: http://curl.haxx.se/ca/cacert.pem
收件人: /Applications/AMPPS/extra/etc/openssl/certs/cacert.pem
并使用该路径更新 php.ini
并重新启动 Apache:
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"
openssl.cafile="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"
并在 Windows AMPPS 安装中应用了相同的设置,并且在其中也可以完美运行。
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/Ampps/php/extras/ssl/cacert.pem"
openssl.cafile="C:/Ampps/php/extras/ssl/cacert.pem"
: wamp 也一样。
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"
openssl.cafile="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"
如果您正在寻找使用 SAN 为 localhost 生成新 SSL 证书,this post 上的步骤对我在Centos 7 / Vagrant / Chrome Browser
有效。
【讨论】:
【参考方案15】:如果上述解决方案都不适合您,请尝试将您的 XAMPP 安装更新到较新的版本。
我使用 php 5.5.11 运行 XAMPP,但完全相同的代码不起作用,我使用 php 5.6.28 升级到 XAMPP 并且上述解决方案有效。
此外,仅更新 PHP 也不起作用,这似乎是该版本 XAMPP 上 apache 和 php 设置的组合。
希望对某人有所帮助。
【讨论】:
【参考方案16】:我在 AppVeyor 中构建应用时遇到了同样的问题。
下载https://curl.haxx.se/ca/cacert.pem到c:\php
启用 openssl echo extension=php_openssl.dll >> c:\php\php.ini
找到证书echo curl.cainfo=c:\php\cacert.pem >> c:\php\php.ini
【讨论】:
【参考方案17】:上述步骤虽然有帮助,但在 Windows 8 上对我不起作用。我不知道相关性,但以下步骤有效。基本上是对 cacert.pem 文件的更改。希望这对某人有所帮助。
从这里下载 cacert.pem 文件: http://curl.haxx.se/docs/caextract.html 将文件保存在您的 PHP 安装文件夹中。 (例如:如果使用 xampp – 将其保存在 c:\Installation_Dir\xampp\php\cacert.pem)。 打开您的 php.ini 文件并添加以下行: curl.cainfo=”C:\Installation_Dir\xampp\php\cacert.pem” openssl.cafile=”C:\Installation_Dir\xampp\php\cacert.pem” 重新启动您的 Apache 服务器,这应该可以修复它(只需停止并启动 服务)。【讨论】:
【参考方案18】:当您查看http://curl.haxx.se/docs/caextract.html 页面时,您会注意到一个大写的部分,名为:
RSA-1024 已移除
阅读它,然后下载包含“RSA-1024”证书的证书版本。 https://github.com/bagder/ca-bundle/blob/e9175fec5d0c4d42de24ed6d84a06d504d5e5a09/ca-bundle.crt
这些将与 Mandrill 一起使用。
禁用 SSL 是个坏主意。
【讨论】:
这解决了我一整天都在努力解决的 AWS/Guzzle/cURL 问题。谢谢! @voidstate 我知道这是旧的,但你也可以使用这个 ['verify' => false] 在 guzzle 中绕过它,有关 ssl/curl/guzzle 的完整文档请点击此处guzzle.readthedocs.org/en/latest/… @John 但这会禁用 SSL 验证,这不是您想要做的,所以我不建议这样做。 对于 Windows,您需要将文件保存在您的服务器上(例如,保存到 C:\curl\curl-ca-bundle.crt),然后将以下内容添加到您的 php.ini 中: [curl] curl.cainfo="C:/curl/curl-ca-bundle.crt" [openssl] openssl.cafile="C:/curl/curl-ca-bundle.crt" 在它完美运行多年(甚至在服务器更改后幸存下来)之后,我才拥有它,但我无法准确理解这里发生了什么。是否 curl 或 openssl 已更新并拥有它;s ca-bundle 更改为与 mailchimp 不兼容的一个?以上是关于PHP - SSL 证书错误:无法获取本地颁发者证书的主要内容,如果未能解决你的问题,请参考以下文章
cURL 错误 60 - SSL 证书问题 - 无法获取本地颁发者
如何在本地使用 wamp 时摆脱 payum“SSL 证书问题:无法获取本地颁发者证书”错误
Paypal Access - SSL 证书:无法获取本地颁发者证书