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

现在,当我卷曲启用HTTPS的站点时,我得到以下异常


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


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

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

#1 楼

curl曾经包含一个接受的证书颁发机构(CA)的列表,但是从7.18.1起,不再捆绑任何CA证书。因此,默认情况下,它将拒绝所有TLS / SSL证书为不可验证。
您必须获取CA的根证书,然后将其指向卷曲。可以在curl的TLS / SSL证书验证详细信息中找到更多信息。

评论


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

– Josnidhin
2011年6月19日15:51

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

– Marc B
2011年6月19日在16:29

就是这样-将CURLOPT_SSL_VERIFYPEER设置为false会破坏使用SSL的目的。

–直到
13年5月7日在12:21

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

–马克·福克斯
2014年2月23日下午5:38

没有真实性,加密您发送的数据有什么意义?如果您已经被MITM了,那么数据还是会被泄露

–hdgarrood
14年8月16日在6:55

#2 楼

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

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


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

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

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


评论


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

–乔纳森·尼科尔(Jonathan Nicol)
2013年9月26日下午2:21

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

– http203
14年5月2日在18:43

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

– mujaffars
2014年8月11日在11:43



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

–内特
2014年9月7日,下午3:07

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

– qbolec
16 Mar 11 '16 at 18:42

#3 楼

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

但是对我有用的一个非常简单的解决方法是在调用之前调用:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);




curl_exec():


php文件中。

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

评论


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

–布鲁诺
2012年5月14日0:46



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

–克里斯·杜特洛(Chris Dutrow)
2012年5月16日在21:11

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

–伊利亚(Ilija)
13年11月24日在21:50

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

– Kenyakorn Ketsombut
15年3月13日在4:28

...“每个对SSL都了解甚少的人” ...,您会惊讶地发现,有很多人甚至不愿对SSL / TLS的基础有所了解,在此处复制/粘贴其错误消息的快速修复。

–布鲁诺
15年3月13日在12:54



#4 楼

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


卷曲:SSL证书问题,请验证CA证书没问题

2006年4月7日

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

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_VERIFYHOST也可能需要为TRUE或FALSE CURLOPT_SSL_VERIFYPEER被禁用(默认为2)。将
CURLOPT_SSL_VERIFYHOST设置为2(这是默认值)将确保
要提供给您的证书具有与您用于访问远程资源的URN相匹配的“通用名”。这是一个健康的检查,但不能保证您的程序没有被欺骗。

输入“中间人”

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

击败“中间人”

我们需要验证证书是否为呈现给我们的
是真实的。我们通过将其与我们
合理*信任的证书进行比较来做到这一点。

如果远程资源受主要CA之一(如Verisign,GeoTrust)颁发的证书保护,等等,您可以安全地将
与Mozilla的CA证书包进行比较,该证书包可以从
http://curl.haxx.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

评论


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

–丹·赫德(Dan Herd)
2012年9月20日上午11:11

抱歉,我已经离开了,是的,我感谢Dan,并更新了《邮报》

– Deepak Oberoi
2013年12月17日上午11:59

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

–GTodorov
2014年12月3日21:41

#5 楼

上面的解决方案很棒,但是如果您使用的是WampServer,则可能会发现在curl.cainfo中设置php.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.cafile PHP配置变量设置为PEM文件路径。

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

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

评论


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

–knezmilos
17年4月24日在7:53

@knezmilos您如何设置openssl.cafile?您在哪里下载的,如何激活它?

– Krys
18-2-5在13:22

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

–knezmilos
18-2-5在13:24



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

– JTG
19年7月10日在17:38

#7 楼

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

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

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


#8 楼

我在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"


评论


很好,谢谢!我更新了问题,以准确添加为我解决问题的方法,而不是创建另一个答案。

– Tim
18-10-30在7:50

#9 楼

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

评论


我希望php.ini应该指向pem文件而不是其父文件夹

–dejjub-AIS
2015年10月2日在20:59

#10 楼

当试图使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 /搜索链中的其他人。


https://pki.google.com/
https://www.geotrust.com/resources/root-certificates/index.html

它们看起来像this:



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

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

#11 楼

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

#12 楼

解决方法很简单!将这行放在curl_exec之前:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);


对我来说它起作用。

评论


永远不要禁用对等验证,除非您不在乎数据在传输中是否受到损害。

–rdlowrey
2014年3月2日在1:37

同意如果您想要一个安全的应用程序,则需要对等验证。

–布莱登
2014年8月8日在16:56

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

–亚当F
2014年11月3日在22:27

@AdamF仅供参考,浏览器默认会验证对等证书,它们只为您提供手动绕过错误并带有警告的选项。

–布鲁诺
15年3月13日在12:57