通过https:SSL3_GET_SERVER_CERTIFICATE使用php加载外部xml文件时出错

时间:2015-09-17 02:58:23

标签: php xml

我无法加载xml文件。

此代码效果很好:

$url = 'http://www.w3schools.com/xml/note.xml';
$xml = simplexml_load_file($url);
print_r($xml);

但是这个

$url = 'https://www.boardgamegeek.com/xmlapi2/thing?id=105551';
$xml = simplexml_load_file($url);
print_r($xml);

不起作用。我收到这个错误:

  

警告:simplexml_load_file():SSL操作失败,代码为1. OpenSSL错误消息:错误:14090086:SSL例程:SSL3_GET_SERVER_CERTIFICATE:证书验证在/storage/content/59/113059/boardgamelevelup.com/public_html/index中失败。第19行的php警告:simplexml_load_file():无法在第19行的/storage/content/59/113059/boardgamelevelup.com/public_html/index.php中启用加密警告:simplexml_load_file(https://www.boardgamegeek.com/xmlapi2/thing?id=105551):无法打开stream:第19行/storage/content/59/113059/boardgamelevelup.com/public_html/index.php中的操作失败警告:simplexml_load_file():I / O警告:无法加载外部实体“https://www.boardgamegeek.com/xmlapi2/thing?id=105551”第19行/storage/content/59/113059/boardgamelevelup.com/public_html/index.php

boardgamegeek的xml文件适用于其他网站。我应该使用不同的PHP代码加载该xml文件吗?

2 个答案:

答案 0 :(得分:5)

简短的食谱回答:

  1. 下载https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt并将该文件放在您的服务器上。
  2. 添加

    $context = stream_context_create(array('ssl'=>array(
        'verify_peer' => true,
        'cafile' => '/path/to/ca-bundle.crt'
    )));
    libxml_set_streams_context($context);
  3. 到您的脚本,以便在simplexml_load_file()之前执行。
    或者 - 而不是上面的代码 - 在php.ini中设置openssl.cafile=/path/to/ca-bundle.crt

    非常简短的解释:
    您的php版本使用openssl来处理http s 传输。 openssl试图验证服务器是否真的是它声称的那个。它通过检查其证书是否可信来实现。 X.509证书包含有关所有者的一些数据,并由颁发者签署(本身具有再次签名的证书,依此类推,直到所有者和发行者相同的证书 - >自签名/根证书) 。证书被视为"信任"如果在那个证书链中有(至少)一个证书,openssl"表示":"好的,我已经指示信任这个" 。该指令的形式为(或可以采取形式)"这里是一个包含您应该信任的证书的文件" (凭证档案错误)。
    上面的代码告诉php的libxml-wrapper告诉openssl当simplexml_load_file使用https / openssl-wrapper时该cafile的位置。
    openssl.cafile=/path/to/ca-bundle.crt只是将其设为默认值;除非另有说明,否则所有openssl操作都将使用该文件 - 包括libxml / simple_xml_loadfile。

    与我联系的ca-bundle.crt来自一个"声称"提供随mozilla firefox一起提供的提取的根证书。关于"声明":我没有理由怀疑这确实是未被禁止的根证书列表;但是你永远不会知道:你在这个项目中放弃了你的信任a)b)mozilla做得很好,只把可信赖的证书放在那个清单中......

    有关详细说明,请参阅http://phpsecurity.readthedocs.org/en/latest/Transport-Layer-Security-%28HTTPS-SSL-and-TLS%29.html#php-streams

答案 1 :(得分:3)

@VolkerK显示的工作和示例非常简单。 尽管这种方法对我不起作用,但我又向前迈了一步,目前暂时删除了安全性。

$context = stream_context_create(array('ssl'=>array(
    'verify_peer' => false, 
    "verify_peer_name"=>false
    )));

libxml_set_streams_context($context);

$sxml = simplexml_load_file($webhostedXMLfile);

是的,这是不好的做法,但是有时您需要临时修复而不是像这样的消息:

警告:simplexml_load_file():SSL操作失败,代码为1。 OpenSSL错误消息:错误:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败 /srv/www/resources/public_html/files/etc/file.php,第150行警告: simplexml_load_file():无法启用加密 /srv/www/resources/public_html/files/etc/file.php,第150行

我希望它可以帮助其他人。