我一直在尝试从我在服务器上创建的PHP页面访问这个特定的REST服务 . 我将问题缩小到这两行 . 所以我的PHP页面如下所示:
<?php
$response = file_get_contents("https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042+N+1050+W&outFields=*&outSR=102100&searchExtent=&f=json");
echo $response; ?>
该页面在第2行死亡,并出现以下错误:
警告:file_get_contents():SSL操作失败,代码为1. OpenSSL错误消息:错误:14090086:SSL例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败...第2行的php警告:file_get_contents():无法启用加密 . 第2行的..php警告:file_get_contents(https://maps.co.weber.ut.us/arcgis/rest/services/SDE_composite_locator/GeocodeServer/findAddressCandidates?Street=&SingleLine=3042 N 1050 W&outFields = *&outSR = 102100&searchExtent = &f = json):无法打开流:第2行的php运行失败
我们正在使用Gentoo服务器 . 我们最近升级到PHP 5.6版 . 升级后出现此问题 .
当我用一个像 https://www.google.com
这样的地址替换REST服务时,我发现了我的页面工作正常 .
在之前的尝试中,我设置了 “verify_peer”=>false
,并将其作为参数传递给file_get_contents,如下所述:file_get_contents ignoring verify_peer=>false?但是就像作者所说的那样;它没有任何区别 .
我问过我们的服务器管理员是否存在php.ini文件中的这些行:
-
extension = php_openssl.dll
-
allow_url_fopen =开
他告诉我,因为我们在Gentoo上,openssl是在我们构建时编译的;并且它没有在php.ini文件中设置 .
我也确认 allow_url_fopen
正在运作 . 由于这个问题的专业性;我没有找到很多帮助信息 . 有没有人遇到过这样的事情?谢谢 .
15 回答
这是一个非常有用的链接,可以找到:
http://php.net/manual/en/migration56.openssl.php
一个官方文档描述了在PHP 5.6中打开ssl所做的更改从这里我学到了另一个我应该设置为false的参数:“verify_peer_name”=> false
所以我的工作代码如下所示:
你不应该只关闭验证 . 相反,你应该下载一个证书包,也许curl捆绑包会做什么?
然后你只需要把它放在你的web服务器上,给运行php权限的用户读取文件 . 那么这段代码应该适合你:
希望您尝试访问的站点的根证书位于curl包中 . 如果不是,则在获得站点的根证书并将其放入证书文件之前,这仍然无效 .
我通过确保在我的机器上安装了OpenSSL然后将其添加到我的php.ini来修复此问题:
您可以通过编写使用curl的自定义函数来解决此问题,如下所示:
然后,只要您调用以https开头的网址,只需使用
file_get_contents_curl
而不是file_get_contents
.如果您的PHP版本是5,请尝试通过在终端中键入以下命令来安装cURL:
您基本上必须将环境变量SSL_CERT_FILE设置为从以下链接下载的ssl-certificate的PEM文件的路径:http://curl.haxx.se/ca/cacert.pem .
我花了很多时间来解决这个问题 .
以下步骤将解决此问题,
从以下链接下载CA证书:https://curl.haxx.se/ca/cacert.pem
查找并打开php.ini
查找
curl.cainfo
并将 absolute path 粘贴到您下载证书的位置 .curl.cainfo ="C:\wamp\htdocs\cert\cacert.pem"
重启WAMP / XAMPP(apache服务器) .
它有效!
希望有所帮助!!
只是想添加到这个,因为我遇到了同样的问题,我找不到任何地方都可以工作(例如下载cacert.pem文件,在php.ini中设置cafile等)
如果您使用的是NGINX,并且您的SSL证书附带了“中间证书”,则需要将中间证书文件与主“mydomain.com.crt”文件合并,它应该可以正常工作 . Apache具有针对中间证书的特定设置,但NGINX不具有此设置,因此它必须与常规证书位于同一文件中 .
此错误的原因是PHP没有受信任的证书颁发机构列表 .
PHP 5.6及更高版本尝试自动加载系统信任的CA.问题可以解决 . 有关更多信息,请参见http://php.net/manual/en/migration56.openssl.php .
PHP 5.5及更早版本很难正确设置,因为您必须在每个请求上下文中手动指定CA包,这是您不希望在代码周围散布的内容 . 所以我决定我的代码,对于PHP版本<5.6,SSL验证只是被禁用:
在我的开发人员机器(php 7,Windows上的xampp)上有一个自签名证书尝试打开“https://localhost/ ...”文件的同一个ssl问题 . 显然,root-certificate-assembly(cacert.pem)不起作用 . 我只是手动复制了下载的cacert.pem中的apache server.crt-File中的代码,并在php.ini中执行了openssl.cafile = path / to / cacert.pem条目
在XAMPP和OSX上与PHP 7有相同的错误 .
https://stackoverflow.com/中的上述答案很好,但它并没有完全解决我的问题 . 我必须提供完整的证书链才能使file_get_contents()再次运行 . 这就是我做到的方式:
Get root / intermediate certificate
首先,我必须弄清楚根和中间证书是什么 .
最方便的方法可能是像ssl-shopper这样的在线证书工具
在那里,我发现了三个证书,一个服务器证书和两个链证书(一个是根,另一个是中间人) .
我需要做的只是在互联网上搜索它们 . 就我而言,这是根:
thawte DV SSL SHA256 CA
它导致他的网址thawte.com . 所以我只是把这个证书放到一个文本文件中,并为中间文件做了同样的事情 . 完成 .
Get the host certificate
接下来我必须下载我的服务器证书 . 在Linux或OS X上,可以使用openssl完成:
Now bring them all together
现在只需将它们合并到一个文件中即可 . (也许将它们放入一个文件夹是很好的,我只是将它们合并到一个文件中) . 你可以这样做:
tell PHP where to find the chain
有一个方便的函数openssl_get_cert_locations(),它会告诉你PHP在哪里寻找cert文件 . 并且有这个参数,它将告诉file_get_contents()在哪里查找cert文件 . 也许两种方式都可行 . 我更喜欢参数方式 . (与上述解决方案相比) .
所以现在这是我的PHP代码
就这样 . file_get_contents()再次运行 . 没有CURL,希望没有安全漏洞 .
在将php更新到php5.6之后,在centOS上成为这个问题的受害者之后,我找到了一个适合我的解决方案 .
默认情况下,获取正确的证书目录
然后使用它来获取证书并将其放在上面代码中找到的默认位置
关于类似的错误
[2017年5月11日19:19:13 America / Chicago] PHP警告:file_get_contents():SSL操作失败,代码为1. OpenSSL错误消息:错误:14090086:SSL例程:ssl3_get_server_certificate:证书验证失败
您是否检查过openssl引用的证书和目录的权限?
你可以这样做
得到类似的东西
这个问题让我感到沮丧,直到我意识到我的"certs"文件夹有700个权限,当它应该拥有755个权限时 . 请记住,这不是密钥的文件夹,而是证书 . 我建议读这个this link on ssl permissions.
我曾经做过
问题是固定的,至少对我来说是这样 .
使用
wget
或file_get_contents
时,我在另一个安全页面遇到了同样的问题 . 许多研究(包括对这个问题的一些回答)产生了一个简单的解决方案 - 安装Curl和PHP-Curl - 如果我已经正确理解,Curl有Comodo的根CA解决了这个问题安装Curl和PHP-Curl插件,然后重启Apache
现在都在工作 .
为我工作,我使用的是PHP 5.6 . openssl扩展应该启用,并在调用google map api verify_peer make false下面的代码对我有用 .