HTTPS 和 SSL3_GET_SERVER_CERTIFICATE:证书验证失败,CA 正常

发布于 2024-11-16 06:29:27 字数 493 浏览 0 评论 0 原文

我正在使用 XAMPP 进行开发。最近我将 xampp 的安装从旧版本升级到 1.7.3。

现在,当我卷曲启用 HTTPS 的网站时,出现以下异常

致命错误:未捕获带有消息的异常“RequestCore_Exception” 'cURL资源:资源 编号#55; cURL 错误:SSL 证书有问题,请验证 CA 证书是否正常。细节: 错误:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败 (60)'

每个人都建议使用PHP代码中的一些特定的curl选项来解决此问题。我认为这不应该是这样。因为我的旧版本 XAMPP 没有任何问题,只是在安装新版本后才发生。

我需要帮助来弄清楚 PHP 安装中的哪些设置发生了变化,Apache 等可以解决这个问题。

I am using XAMPP for development. Recently I upgraded my installation of xampp from an old version to 1.7.3.

Now when I curl HTTPS enabled sites I get the following exception

Fatal error: Uncaught exception 'RequestCore_Exception' with message
'cURL resource: Resource
id #55; cURL error: SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (60)'

Everyone suggest using some specific curl options from PHP code to fix this problem. I think this shouldn't be the way. Because I didn't have any problem with my old version of XAMPP and happened only after installing the new version.

I need help to figure out what settings change in my PHP installation, Apache etc can fix this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

两相知 2024-11-23 06:29:27

这是 Windows 中非常常见的问题。您只需将 cacert.pem 设置为 curl.cainfo 即可。

从 PHP 5.3.7 开始,您可以执行以下操作:

  1. 下载 https://curl.se/ca/cacert.pem< /a> 并将其保存在某个地方。
  2. 更新 php.ini -- 添加curl.cainfo = "PATH_TO/cacert.pem"

否则,您需要对每个 cURL 资源执行以下操作:

curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");

It's a pretty common problem in Windows. You need just to set cacert.pem to curl.cainfo.

Since PHP 5.3.7 you could do:

  1. download https://curl.se/ca/cacert.pem and save it somewhere.
  2. update php.ini -- add curl.cainfo = "PATH_TO/cacert.pem"

Otherwise you will need to do the following for every cURL resource:

curl_setopt ($ch, CURLOPT_CAINFO, "PATH_TO/cacert.pem");
你怎么这么可爱啊 2024-11-23 06:29:27

curl 过去包含接受的证书颁发机构 (CA) 列表,但自 7.18.1 及更高版本起不再捆绑任何 CA 证书。因此,默认情况下,它会拒绝所有 TLS/SSL 证书,因为它们无法验证。

您必须获取 CA 的根证书并指向它。更多详细信息,请参阅curl 的有关 TLS/SSL 证书验证的详细信息

curl used to include a list of accepted certificate authorities (CAs) but no longer bundles ANY CA certs since 7.18.1 and onwards. So by default it'll reject all TLS/SSL certificates as unverifiable.

You'll have to get your CA's root certificate and point curl at it. More details at curl's details on TLS/SSL certificates verification.

花落人断肠 2024-11-23 06:29:27

警告:这可能会引入 SSL 旨在防止的安全问题,从而使整个代码库变得不安全。它违背了所有推荐的做法。

调用:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

之前调用:

curl_exec():

但对我来说一个非常简单的修复方法是在 php 文件中

。我认为这会禁用 SSL 证书的所有验证。

Warning: this can introduce security issues that SSL is designed to protect against, rendering your entire codebase insecure. It goes against every recommended practice.

But a really simple fix that worked for me was to call:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

before calling:

curl_exec():

in the php file.

I believe that this disables all verification of SSL certificates.

戒ㄋ 2024-11-23 06:29:27

来源:http://ademar.name /blog/2006/04/curl-ssl-certificate-problem-v.html

#Curl: SSL 证书问题,请验证 CA 证书是否正常#
###2006 年 4 月 7 日###

使用 Curl 打开安全 URL 时,您可能会收到以下错误:

SSL 证书问题,请验证 CA 证书是否正常

我将解释错误的原因以及您应该采取的措施。

消除错误的最简单方法是添加
在您的脚本中添加以下两行。该解决方案提供了安全性
不过有风险。

//警告:这将阻止curl检测到“中间人”攻击
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 

让我们看看这两个参数的作用。引用手册。

CURLOPT_SSL_VERIFYHOST:1 检查 SSL 对等证书中是否存在通用名称。 2 检查通用名称是否存在
并验证它是否与提供的主机名匹配。

CURLOPT_SSL_VERIFYPEER:FALSE 阻止 CURL 验证对等点的证书。用于验证的备用证书可以是
使用 CURLOPT_CAINFO 选项或证书目录指定
可以使用 CURLOPT_CAPATH 选项指定。
CURLOPT_SSL_VERIFYHOST 可能还需要为 TRUE 或 FALSE,如果
CURLOPT_SSL_VERIFYPEER 已禁用(默认为 2)。环境
CURLOPT_SSL_VERIFYHOST 为 2(这是默认值)将保证
向您提供的证书有一个“通用名称”
与您用于访问远程资源的 URN 匹配。这是
一个健康的检查,但它并不能保证你的程序不会被
被骗了。

###输入“中间人”###

您的程序可能会被误导与另一台服务器对话
反而。这可以通过多种机制来实现,例如 dns 或
arp 中毒(这是另一天的故事)。入侵者可以
还可以使用与您的程序相同的“通用名称”来自签名证书
正在期待。通信仍然会被加密,但您会
将你的秘密泄露给冒名顶替者。这种攻击是
称为“中间人”

###击败“中间人”###

好吧,我们需要验证向我们提供的证书是
确实有好处。我们通过将其与我们的证书进行比较来做到这一点
合理*信任。

如果远程资源受以下机构之一颁发的证书保护
主要的 CA,如 Verisign、GeoTrust 等,您可以安全地进行比较
针对 Mozilla 的 CA 证书捆绑包,您可以从中获取
http://curl.se/docs/caextract.html

将文件 cacert.pem 保存在服务器中的某个位置并设置
脚本中的以下选项。

curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, TRUE); 
curl_setopt ($ch, CURLOPT_CAINFO, "pathto/cacert.pem");

以上所有信息来源:http:// ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html

Source: http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html

#Curl: SSL certificate problem, verify that the CA cert is OK#
###07 April 2006###

When opening a secure url with Curl you may get the following error:

SSL certificate problem, verify that the CA cert is OK

I will explain why the error and what you should do about it.

The easiest way of getting rid of the error would be adding the
following two lines to your script . This solution poses a security
risk tho.

//WARNING: this would prevent curl from detecting a 'man in the middle' attack
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); 

Let see what this two parameters do. Quoting the manual.

CURLOPT_SSL_VERIFYHOST: 1 to check the existence of a common name in the SSL peer certificate. 2 to check the existence of a common name
and also verify that it matches the hostname provided.

CURLOPT_SSL_VERIFYPEER: FALSE to stop CURL from verifying the peer's certificate. Alternate certificates to verify against can be
specified with the CURLOPT_CAINFO option or a certificate directory
can be specified with the CURLOPT_CAPATH option.
CURLOPT_SSL_VERIFYHOST may also need to be TRUE or FALSE if
CURLOPT_SSL_VERIFYPEER is disabled (it defaults to 2). Setting
CURLOPT_SSL_VERIFYHOST to 2 (This is the default value) will garantee
that the certificate being presented to you have a 'common name'
matching the URN you are using to access the remote resource. This is
a healthy check but it doesn't guarantee your program is not being
decieved.

###Enter the 'man in the middle'###

Your program could be misleaded into talking to another server
instead. This can be achieved through several mechanisms, like dns or
arp poisoning ( This is a story for another day). The intruder can
also self-sign a certificate with the same 'comon name' your program
is expecting. The communication would still be encrypted but you would
be giving away your secrets to an impostor. This kind of attack is
called 'man in the middle'

###Defeating the 'man in the middle'###

Well, we need to to verify the certificate being presented to us is
good for real. We do this by comparing it against a certificate we
reasonable* trust.

If the remote resource is protected by a certificate issued by one of
the main CA's like Verisign, GeoTrust et al, you can safely compare
against Mozilla's CA certificate bundle which you can get from
http://curl.se/docs/caextract.html

Save the file cacert.pem somewhere in your server and set the
following options in your script.

curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, TRUE); 
curl_setopt ($ch, CURLOPT_CAINFO, "pathto/cacert.pem");

for All above Info Credit Goes to : http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html

苍白女子 2024-11-23 06:29:27

上述解决方案很棒,但如果您使用 WampServer,您可能会发现在 php.ini 中设置 curl.cainfo 变量不起作用。

我最终发现 WampServer 有两个 php.ini 文件:

C:\wamp\bin\apache\Apachex.x.x\bin
C:\wamp\bin\php\phpx.x.xx

第一个显然用于通过 Web 浏览器调用 PHP 文件,而第二个用于通过命令行或 <代码>shell_exec()

TL;DR

如果使用 WampServer,则必须将 curl.cainfo 行添加到两个 php.ini 文件中。

The above solutions are great, but if you're using WampServer you might find setting the curl.cainfo variable in php.ini doesn't work.

I eventually found WampServer has two php.ini files:

C:\wamp\bin\apache\Apachex.x.x\bin
C:\wamp\bin\php\phpx.x.xx

The first is apparently used for when PHP files are invoked through a web browser, while the second is used when a command is invoked through the command line or shell_exec().

TL;DR

If using WampServer, you must add the curl.cainfo line to both php.ini files.

绅士风度i 2024-11-23 06:29:27

出于对所有神圣事物的热爱...

就我而言,我必须将 openssl.cafile PHP 配置变量设置为 PEM 文件路径。

我相信确实有很多系统在 PHP 的配置中设置 curl.cainfo 正是所需要的,但在我正在使用的环境中,这是 eboraas/laravel docker 容器,使用 Debian 8 (jessie) 和 PHP 5.6,设置该变量并没有起到作用。

我注意到 php -i 的输出没有提及有关该特定配置设置的任何内容,但它确实有几行关于 openssl 的内容。同时存在 openssl.capathopenssl.cafile 选项,但只需设置第二个选项即可通过 PHP 进行卷曲,最终可以使用 HTTPS URL。

For the love of all that is holy...

In my case, I had to set the openssl.cafile PHP config variable to the PEM file path.

I trust it is very true that there are many systems where setting curl.cainfo in PHP's config is exactly what is needed, but in the environment I'm working with, which is the eboraas/laravel docker container, which uses Debian 8 (jessie) and PHP 5.6, setting that variable did not do the trick.

I noticed that the output of php -i did not mention anything about that particular config setting, but it did have a few lines about openssl. There is both an openssl.capath and openssl.cafile option, but just setting the second one allowed curl via PHP to finally be okay with HTTPS URLs.

春花秋月 2024-11-23 06:29:27

有时,如果您尝试联系的应用程序具有自签名证书,则来自 http:// 的普通 cacert.pem curl.haxx.se/ca/cacert.pem 不能解决问题。

如果您确定服务端点 URL,请通过浏览器点击它,以“X 509 证书与链 (PEM)”格式手动保存证书。将此证书文件指向

curl_setopt ($ch, CURLOPT_CAINFO, "pathto/{downloaded certificate chain file}");   

Sometimes if the application you try to contact has self signed certificates, the normal cacert.pem from http://curl.haxx.se/ca/cacert.pem does not solve the problem.

If you are sure about the service endpoint url, hit it through browser, save the certificate manually in "X 509 certificate with chain (PEM)" format. Point this certificate file with the

curl_setopt ($ch, CURLOPT_CAINFO, "pathto/{downloaded certificate chain file}");   
好久不见√ 2024-11-23 06:29:27

我在 amazon AMI linux 上遇到同样的错误。

我通过在 /etc/php.d/curl.ini 设置 curl.cainfo 来解决

https://gist.github.com/reinaldomendes/97fb2ce8a606ec813c4b

2018 年 10 月添加

在 Amazon Linux v1 上编辑此文件

vi /etc/php.d/20-curl.ini

要添加此行

curl.cainfo="/etc/ssl/certs/ca-bundle.crt"

I have the same error on amazon AMI linux.

I Solved by setting curl.cainfo on /etc/php.d/curl.ini

https://gist.github.com/reinaldomendes/97fb2ce8a606ec813c4b

Addition October 2018

On Amazon Linux v1 edit this file

vi /etc/php.d/20-curl.ini

To add this line

curl.cainfo="/etc/ssl/certs/ca-bundle.crt"
梦巷 2024-11-23 06:29:27

当为 CURLOPT_CAINFO 设置卷曲选项时,请记住使用单引号,使用双引号只会导致另一个错误。所以你的选项应该是这样的:

curl_setopt ($ch, CURLOPT_CAINFO, 'c:\wamp\www\mywebfolder\cacert.pem');

另外,在你的 php.ini 文件设置中应该写成:(注意我的双引号)

curl.cainfo = "C:\wamp\www\mywebfolder"

我把它直接放在这样的行下面:extension=php_curl.dll

(仅出于组织目的,您可以将其放在 php.ini 中的任何位置,我只是将其放在另一个curl 引用附近,这样当我使用关键字curl 进行搜索时,我可以在一个区域中找到两个curl 引用。 )

When setting the curl options for CURLOPT_CAINFO please remember to use single quotes, using double quotes will only cause another error. So your option should look like:

curl_setopt ($ch, CURLOPT_CAINFO, 'c:\wamp\www\mywebfolder\cacert.pem');

Additionally, in your php.ini file setting should be written as:(notice my double quotes)

curl.cainfo = "C:\wamp\www\mywebfolder"

I put it directly below the line that says this: extension=php_curl.dll

(For organizing purposes only, you could put it anywhere within your php.ini, i just put it close to another curl reference so when I search using keyword curl I caan find both curl references in one area.)

北渚 2024-11-23 06:29:27

当我试图让 GuzzleHttp(Mac 上为 php+apache)从 www.googleapis.com 获取页面时,我最终来到了这里。

这是我的最终解决方案,以防它对任何人有帮助。

查看证书链中是否有任何域向您提供此错误。对我来说,它是 googleapis.com

openssl s_client -host www.googleapis.com -port 443

你会得到这样的结果:

Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.googleapis.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority

注意:我在解决问题后捕获了这个,你的链输出可能看起来不同。

然后你需要查看证书在 php 中允许。在页面中运行 phpinfo()。

<?php echo phpinfo();

然后查找从页面输出加载的证书文件:

openssl.cafile  /usr/local/php5/ssl/certs/cacert.pem

这是您需要通过向其添加正确的证书来修复的文件。

sudo nano /usr/local/php5/ssl/certs/cacert.pem

您基本上需要将正确的证书“签名”附加到该文件的末尾。

您可以在这里找到其中一些:如果您需要它们,您可能需要在链中搜索其他内容。

它们看起来像这样:

示例证书图像

注意:这是一个图像,因此人们不会简单地从 stackoverflow 复制/粘贴证书

一旦正确的证书位于此文件中,请重新启动 apache 并进行测试。

I ended up here when trying to get GuzzleHttp (php+apache on Mac) to get a page from www.googleapis.com.

Here was my final solution in case it helps anyone.

Look at the certificate chain for whatever domain is giving you this error. For me it was googleapis.com

openssl s_client -host www.googleapis.com -port 443

You'll get back something like this:

Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.googleapis.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority

Note: I captured this after I fixed the issue, to your chain output may look different.

Then you need to look at the certificates allowed in php. Run phpinfo() in a page.

<?php echo phpinfo();

Then look for the certificate file that's loaded from the page output:

openssl.cafile  /usr/local/php5/ssl/certs/cacert.pem

This is the file you'll need to fix by adding the correct certificate(s) to it.

sudo nano /usr/local/php5/ssl/certs/cacert.pem

You basically need to append the correct certificate "signatures" to the end of this file.

You can find some of them here: You may need to google/search for others in the chain if you need them.

They look like this:

example certificate image

(Note: This is an image so people will not simply copy/paste certificates from stackoverflow)

Once the right certificates are in this file, restart apache and test.

再见回来 2024-11-23 06:29:27

您可以尝试重新安装 ca-certificates 软件包,或者按照此处

You could try to reinstall the ca-certificates package, or explicitly allow the certificate in question as described here.

请帮我爱他 2024-11-23 06:29:27

解决办法很简单!将此行放在 curl_exec 之前:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

对我来说它有效。

The solution is very simple! Put this line before curl_exec:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

For me it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文