简体   繁体   中英

Error when loading external xml file with php via https : SSL3_GET_SERVER_CERTIFICATE

I can't get a xml file to load.

This code works great:

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

But this one

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

doesn't work. I get this error:

Warning: simplexml_load_file(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /storage/content/59/113059/boardgamelevelup.com/public_html/index.php on line 19 Warning: simplexml_load_file(): Failed to enable crypto in /storage/content/59/113059/boardgamelevelup.com/public_html/index.php on line 19 Warning: simplexml_load_file( https://www.boardgamegeek.com/xmlapi2/thing?id=105551 ): failed to open stream: operation failed in /storage/content/59/113059/boardgamelevelup.com/public_html/index.php on line 19 Warning: simplexml_load_file(): I/O warning : failed to load external entity " https://www.boardgamegeek.com/xmlapi2/thing?id=105551 " in /storage/content/59/113059/boardgamelevelup.com/public_html/index.php on line 19

The xml file from boardgamegeek works on other sites. Should I use a different php code to load that xml file?

short cookbook answer:

  1. Download https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt and place that file on your server.
  2. Add

    $context = stream_context_create(array('ssl'=>array( \n    'verify_peer' => true, \n    'cafile' => '/path/to/ca-bundle.crt' \n))); \nlibxml_set_streams_context($context); 

to your script so it gets executed before simplexml_load_file().
Or - instead of the code above - set openssl.cafile=/path/to/ca-bundle.crt in your php.ini.

Very short explaination:
Your php version uses openssl to handle the http transport.交通。 openssl tries to verify whether the server really is who it claims to be. It does that by checking whether its certificate is trusted. A X.509 certificate contains some data about the owner and is signed by an issuer (itself having a certificate that is again signed and so on and on until a certificate where owner and issuer are identical -> self-signed/root certificate). A certificate is considered "trusted" if in that chain of certificates there is (at least) one certificate on which openssl "says": "ok, I have been instructed to trust this one". This instruction takes the form of (or can take the form of) "here's a file containing certificates that you're supposed to trust" (cafile).
The above code tells the libxml-wrapper of php to tell openssl where that cafile is when simplexml_load_file uses the https/openssl-wrapper.
And openssl.cafile=/path/to/ca-bundle.crt just sets it as default; unless instructed otherwise all openssl operations will use that file - including libxml/simple_xml_loadfile.

The ca-bundle.crt I've linked to is from a project that "claims" to provide the extracted root certificates as shipped with mozilla firefox. Regarding "claims": I have no reason to doubt that this really is the untampered root cert list; but you never know: You're putting your trust a) in this project and b) mozilla doing a good job and only putting trustworthy certificates in that list....

for more explaination see http://phpsecurity.readthedocs.org/en/latest/Transport-Layer-Security-%28HTTPS-SSL-and-TLS%29.html#php-streams

The work and example that @VolkerK displayed was excellent and simple. While this method didn't work for me, I took it one step further and basically removed the security for the moment.

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

libxml_set_streams_context($context);

$sxml = simplexml_load_file($webhostedXMLfile);

Yes, this is bad practice, but sometimes you need a temp fix instead of messages like this:

Warning: simplexml_load_file(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /srv/www/resources/public_html/files/etc/file.php on line 150 Warning: simplexml_load_file(): Failed to enable crypto in /srv/www/resources/public_html/files/etc/file.php on line 150

I hope it helps someone else.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM