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


208

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

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

致命错误:消息为“ cURL资源”的未捕获异常“ Re​​questCore_Exception”;资源ID为55;cURL错误:SSL证书问题,请验证CA证书是否正确。详细信息:错误:14090086:SSL例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败(60)'

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

我需要帮助确定我的PHP安装中有哪些设置更改,Apache等可以解决此问题。

Answers:


145

curl曾经包含可接受的CA列表,但不再捆绑任何CA证书。因此,默认情况下,它将拒绝所有SSL证书为不可验证的证书。

您必须获得CA的证书,然后将证书指向该证书。有关更多详细信息,请参见cURLS的“服务器SSL证书详细信息”


4
卷曲发生在Amazon Web Services php库中。我不了解如何在不编辑库代码的情况下进行修复。
Josnidhin 2011年

41
然后关闭证书验证(CURLOPT_SSL_VERIFYPEER-> false)。您可以添加要使用SSL的网站的CA证书,也可以禁用CA验证。这些是仅有的两个选项。
Marc B,16:

78
只是-设置CURLOPT_SSL_VERIFYPEERfalse失败使用SSL的目的。
直到

13
@Till不会破坏SSL的一半目的吗?您仍然可以在同伴之间获得私密性:您只是没有同伴的真实性。
马克·福克斯

10
没有真实性,对发送的数据进行加密有什么意义?如果您已经被MITM了,那么数据还是会遭到破坏
hdgarrood 2014年

290

在Windows中,这是一个非常普遍的问题。您只需要设置cacert.pem为即可curl.cainfo

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

  1. 下载https://curl.haxx.se/ca/cacert.pem并将其保存在某处。
  2. 更新php.ini-添加curl.cainfo =“ PATH_TO / cacert.pem”

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

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

2
这对我在OS X上的XAMPP起作用。它解决了一个问题,即由于无法找到本地证书,Wordpress插件无法更新。
乔纳森·尼科尔

8
对于尝试使用Apache在Windows上解决此问题的其他用户,我必须在我的PHP代码中设置完整路径(即C:\ PATH_TO \ cacert.pem)。在IIS上,相对路径似乎正常。
http203 2014年

如果cacert.pem在同一目录中,则curl_setopt($ ch,CURLOPT_CAINFO,dirname(FILE)。'/cacert.pem'); 将工作
mujaffars 2014年

7
与WampServer一起使用时2.,必须将变量添加到两个单独的php.ini文件中。请参阅stackoverflow.com/a/25706713/1101095
2014年

令人费解/讽刺的是,您可以通过HTTPS 下载curl.haxx.se/ca/cacert.pem,而无需指定任何其他选项。curl.haxx.se的证书是否本身备份到curl中?
qbolec '16

84

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

但是对我有用的一个非常简单的解决方法是致电:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

致电之前:

curl_exec():

在php文件中。

我相信这会禁用所有SSL证书验证。


65
...并通过禁用证书的验证,就为潜在的MITM攻击敞开了大门,而SSL / TLS旨在防止这种攻击。不要这样做!
布鲁诺

12
对。我应该在答案中更加注意这一点。仅当您不从事任何重要工作时才这样做。我在本地主机上使用它来访问我个人编程的网站。
克里斯·杜特罗

3
拒绝我。这是使代码正常工作的肮脏修补程序,但不是解决方案。АртурКурицын提供的答案要好得多。
伊利亚,2013年

2
@Bruno对于助手脚本,测试,受信任的应用程序,Intranet等,这是一个完美的解决方案。每个了解SSL的人都知道在什么情况下可以跳过证书验证。因此,关于此答案的所有“智能”评论以及诸如“不要这样做”之类的东西都是无意义的!
Kenyakorn Ketsombut 2015年

5
...“ 每个对SSL知之甚少的人......,您会感到惊讶的是,有很多人甚至不愿对SSL / TLS的基础有所了解,在此处复制/粘贴其错误消息的快速修复。
布鲁诺

53

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

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

2006年4月7日

使用Curl打开安全网址时,可能会出现以下错误:

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

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

消除错误的最简单方法是在脚本中添加以下两行。该解决方案带来了安全风险。

//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); 

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

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

CURLOPT_SSL_VERIFYPEER:FALSE阻止CURL验证对等方的证书。可以使用CURLOPT_CAINFO选项指定要验证的备用证书,或者可以使用CURLOPT_CAPATH选项指定证书目录。如果禁用了CURLOPT_SSL_VERIFYPEER(默认值为2),则CURLOPT_SSL_VERIFYHOST也可能需要为TRUE或FALSE。将CURLOPT_SSL_VERIFYHOST设置为2(这是默认值)将确保向您提供的证书具有与您用于访问远程资源的URN匹配的“公用名”。这是健康检查,但不能保证您的程序未被欺骗。

输入“中间人”

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

击败“中间人”

好吧,我们需要验证提交给我们的证书是否真实。为此,我们将其与我们合理*信任的证书进行比较。

如果远程资源受到主要CA之一(如Verisign,GeoTrust等)颁发的证书的保护,则可以与可从http://curl.haxx.se/docs/caextract获得的Mozilla的CA证书包进行比较。 .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


38
通常认为,相信您的信息来源并仅引用与该问题相关的某些部分,而不是简单地在此处复制和粘贴,是礼貌的做法!
Dan Herd

1
抱歉,我已经走了,是的,我为此申请了Dan,并更新了The Post
Deepak Oberoi

6
至少Deepak致力于研究它。@danherd所以danherd,您刚刚进行研究发现他从某个地方拿走了代码?该代码的归属权是什么?不要浪费时间去发现别人的错误,而要自己去帮助别人。不要打架,分享!
GTodorov 2014年

17

上面的解决方案很棒,但是如果您使用的是WampServer,则可能会发现curl.cainfophp.ini中设置变量无效。

我最终发现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文件中。


6

为了爱所有神圣的事物...

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

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

我注意到,的输出php -i未提及有关该特定配置设置的任何内容,但其中确实包含几行openssl。同时有openssl.capathopenssl.cafile选项,但是只需设置第二个选项,就可以通过PHP允许curl最终与HTTPS URL兼容。


谢谢!设置curl.cainfo也不适合我,但是设置openssl.cafile可以!我在Windows 7上使用XAMPP和PHP 7.1.1。
knezmilos

@knezmilos您如何设置openssl.cafile?您在哪里下载的,如何激活它?
克里斯(Krys)'18年

好吧,已经有一段时间了,但是我认为它是这样的:php中的curl.cainfo =“ C:\ xampp \ cacert \ cacert.pem”和openssl.cafile =“” C:\ xampp \ cacert \ cacert.pem“。 ini,虽然我认为我从这里的答案之一中得到了pem文件。
knezmilos

1
确实是“为了对所有圣洁者的爱……”。这适用于我的Ubuntu 18.08 / Apache / Php7.2设置。如果curl错误指向正确的文件,则很可能是openssls错误
JTG

4

有时,如果您尝试联系的应用程序具有自签名证书,则http://curl.haxx.se/ca/cacert.pem中的常规cacert.pem 无法解决问题。

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

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


3

为CURLOPT_CAINFO设置curl选项时,请记住使用单引号,使用双引号只会导致另一个错误。因此,您的选择应如下所示:

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引用。)


1
我希望php.ini应该指向pem文件而不是其父文件夹
dejjub-AIS 2015年

2

当试图使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

基本上,您需要在此文件的末尾附加正确的证书“签名”。

您可以在这里找到其中的一些:如果需要,您可能需要Google /搜索链中的其他人。

他们看起来像这样:

证书图片示例

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

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


0

您可以尝试重新安装ca-certificates软件包,或按此处所述明确允许有问题的证书。


-5

解决方法很简单!将此行放在curl_exec

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

对我来说,它有效。


7
永远,永远禁止对等认证,除非你不如果数据在传输过程中受到损害在意。
rdlowrey'3

同意 如果您想要安全的应用程序,则需要对等验证。
布雷登2014年

2
“永远不要禁用对等验证”,除非您想要默认浏览器功能。另外,为什么这么低估呢?这是简短有效的唯一答案。
亚当F

@AdamF仅供参考,浏览器默认情况下会验证对等证书,它们只为您提供手动绕过错误并带有警告的选项。
布鲁诺
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.