fichier get contents (): l'opération SSL a échoué avec le code 1. Et plus

j'ai essayé d'accéder à ce service REST particulier à partir d'une page PHP que j'ai créée sur notre serveur. J'ai réduit le problème à ces deux lignes. Ainsi, ma page PHP ressemble à ceci:

<?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; ?>

la page meurt sur la ligne 2 avec les erreurs suivantes:

  • avertissement: file_get_contents(): l'opération SSL a échoué avec le code 1. Messages d'erreur OpenSSL: erreur: 14090086: SSL routines: SSL3_GET_SERVER_CERTIFICATE: certificat échec de la vérification ...php sur la ligne 2
    • Warning: file_get_contents(): impossible d'activer les crypto ...php sur ligne 2
    • avertissement: 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 ): failed to open stream: échec de l'opération ...php sur la ligne 2

nous utilisons un serveur Gentoo. Nous avons récemment mis à jour la version 5.6 de PHP. Il après la mise à niveau lorsque ce problème est apparu.

j'ai trouvé quand je remplace le service de repos avec une adresse comme https://www.google.com ; ma page fonctionne très bien.

dans une tentative précédente, j'ai placé “verify_peer”=>false , et passé cela en argument à file_get_contents, comme décrit ici: file_get_contents ignoring verify_peer= > false? mais comme l'a noté l'auteur, cela n'a fait aucune différence.

j'ai demandé l'un de nos administrateurs de serveur si ces lignes dans notre php.le fichier ini existe:

  • extension=php_openssl.dll
  • allow_url_fopen = On

il m'a dit que puisque nous sommes sur Gentoo, openssl est compilé lorsque nous construisons; et il n'est pas défini dans le php.fichier ini.

j'ai aussi confirmé que allow_url_fopen . En raison de la nature spécialisée de ce problème, Je ne trouve pas beaucoup de informations pour obtenir de l'aide. N'avez-vous venir à travers quelque chose comme ça? Grâce.

123
demandé sur Community 2014-10-01 23:04:50

14 réponses

C'était un lien extrêmement utile pour trouver:

http://php.net/manual/en/migration56.openssl.php

un document officiel décrivant les modifications apportées à open ssl en PHP 5.6 De là, j'ai appris un autre paramètre que j'aurais dû définir à false: "verify_peer_name"= > false

donc mon code de travail ressemble à ceci:

<?php
$arrContextOptions=array(
    "ssl"=>array(
        "verify_peer"=>false,
        "verify_peer_name"=>false,
    ),
);  

$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", false, stream_context_create($arrContextOptions));

echo $response; ?>
206
répondu Joe 2014-10-01 22:56:00

vous ne devriez pas désactiver la vérification. Vous devriez plutôt télécharger un paquet de certificat, peut-être le paquet curl fera l'affaire?

Ensuite, vous avez juste besoin de le mettre sur votre serveur web, en donnant à l'utilisateur qui exécute php autorisation de lire le fichier. Ce code devrait fonctionner pour vous:

$arrContextOptions=array(
    "ssl"=>array(
        "cafile" => "/path/to/bundle/cacert.pem",
        "verify_peer"=> true,
        "verify_peer_name"=> true,
    ),
);

$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", false, stream_context_create($arrContextOptions));

avec un peu de chance, le certificat racine du site auquel vous tentez d'accéder est dans le paquet curl. Si elle ne l'est pas, c'est encore ne fonctionnera pas jusqu'à ce que vous obtenir le certificat racine du site et le mettre dans votre fichier de certificat.

118
répondu elitechief21 2017-04-13 15:51:18

j'ai corrigé ceci en m'assurant que cette OpenSSL était installée sur ma machine et en ajoutant ceci à mon php.ini:

openssl.cafile=/usr/local/etc/openssl/cert.pem
23
répondu andlin 2016-10-01 13:33:00

Vous pouvez contourner ce problème en écrivant une fonction personnalisée qui utilise curl, comme dans:

function file_get_contents_curl( $url ) {

  $ch = curl_init();

  curl_setopt( $ch, CURLOPT_AUTOREFERER, TRUE );
  curl_setopt( $ch, CURLOPT_HEADER, 0 );
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
  curl_setopt( $ch, CURLOPT_URL, $url );
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, TRUE );

  $data = curl_exec( $ch );
  curl_close( $ch );

  return $data;

}

alors il suffit d'utiliser file_get_contents_curl au lieu de file_get_contents chaque fois que vous appelez une url qui commence par https.

9
répondu Ben Shoval 2016-10-28 18:29:12

si votre version PHP est 5, essayez d'installer cURL en tapant la commande suivante dans le terminal:

sudo apt-get install php5-curl
9
répondu ARUNBALAN NV 2018-01-16 06:56:10

vous avez essentiellement à définir la variable D'environnement SSL_CERT_FILE au chemin du fichier PEM du certificat ssl téléchargé à partir du lien suivant: http://curl.haxx.se/ca/cacert.pem .

Il m'a fallu beaucoup de temps pour comprendre cela.

7
répondu Kshitij Mittal 2017-01-09 08:46:56

la suite des étapes ci-dessous va corriger cette question,

  1. Téléchargez le certificat CA À partir de ce lien: https://curl.haxx.se/ca/cacert.pem
  2. trouver et ouvrir php.ini
  3. rechercher curl.cainfo et coller le chemin absolu où vous avez télécharger le certificat. curl.cainfo ="C:\wamp\htdocs\cert\cacert.pem"
  4. redémarrer WAMP / XAMPP (apache server).
  5. Il fonctionne!

espère que ça aide !!

5
répondu shakee93 2018-04-06 17:02:47

voulait juste ajouter à cela puisque j'ai rencontré le même problème et rien que je pourrais trouver n'importe où fonctionnerait (E. g téléchargement du cacert.fichier pem, configuration de cafile en php.ini etc.)

si vous utilisez NGINX et que votre certificat SSL est livré avec un" certificat intermédiaire", vous devez combiner le fichier intermédiaire cert avec votre "mydomaine" principale.com.crt " et ça devrait marcher. Apache a un paramètre spécifique pour les certs intermédiaires, mais NGINX ne le fait pas, il doit être dans le même fichier que votre certificat régulier.

4
répondu SlickTheNick 2016-02-26 20:40:31

la raison de cette erreur est que PHP n'a pas de liste d'autorités de certification de confiance.

PHP 5.6 et plus tard essayer de charger le CAs confiance par le système automatiquement. Problèmes avec qui peut être fixe. Voir http://php.net/manual/en/migration56.openssl.php pour plus d'information.

PHP 5.5 et plus tôt sont vraiment difficile à configurer correctement puisque vous devez spécifier manuellement le paquet CA dans chaque contexte de requête, une chose que vous ne voulez pas saupoudrer autour de votre code. J'ai donc décidé pour mon code que pour les versions PHP < 5.6, la vérification SSL est tout simplement désactivée:

$req = new HTTP_Request2($url);
if (version_compare(PHP_VERSION, '5.6.0', '<')) {
    //correct ssl validation on php 5.5 is a pain, so disable
    $req->setConfig('ssl_verify_host', false);
    $req->setConfig('ssl_verify_peer', false);
}
3
répondu cweiske 2016-09-06 21:34:02

avait le même problème ssl sur ma machine de développement (php 7, xampp sur windows) avec un certificat auto signé essayant de fopen un " https://localhost / ..."-fichier. De toute évidence, l'assemblage racine-certificat (cacert.pem) n'a pas fonctionné. Je viens de copier manuellement le code du serveur apache.crt-Fichier téléchargé cacert.pem et ne openssl.cafile=chemin/vers/cacert.entrée pem en php.ini

3
répondu hangerer 2017-01-12 15:21:41

avait la même erreur avec PHP 7 sur XAMPP et OSX.

mentionné ci-dessus la réponse dans https://stackoverflow.com/ est bon, mais il n'a pas de résoudre complètement le problème pour moi. J'ai dû fournir la chaîne de certificats complète pour que file_get_contents() fonctionne à nouveau. C'est comme ça que je l'ai fait:

Get root / certificat intermédiaire

tout D'abord je devais comprendre quelle est la racine et le certificat intermédiaire.

le moyen le plus pratique est peut-être un outil en ligne de cert-tool comme le ssl-shopper

là j'ai trouvé trois certificats, un certificat de serveur et deux certificats de chaîne (l'un est la racine, l'autre apparemment l'intermédiaire).

Tout ce que je dois faire est de faire une recherche sur internet pour les deux. Dans mon cas, c'est le racine:

thawte DV SSL SHA256 CA

et ça mène à son url thawte.com . Donc j'ai juste mis ce cert dans un fichier texte et j'ai fait la même chose pour l'intermédiaire. Faire.

Obtenir les certificats de l'ordinateur hôte

la prochaine chose que j'ai dû faire est de télécharger mon serveur cert. Sous Linux ou OS X, cela peut être fait avec openssl:

openssl s_client -showcerts -connect whatsyoururl.de:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > /tmp/whatsyoururl.de.cert

maintenant, rassemblez-les tous

maintenant, fusionnez - les tous en un seul fichier. (Peut-être qu'il est bon de simplement les mettre dans un dossier, je viens de les fusionner dans un fichier). Vous pouvez le faire comme ceci:

cat /tmp/thawteRoot.crt > /tmp/chain.crt
cat /tmp/thawteIntermediate.crt >> /tmp/chain.crt
cat /tmp/tmp/whatsyoururl.de.cert >> /tmp/chain.crt

dites à PHP où trouver la chaîne

il y a cette fonction très pratique openssl_get_cert_locations() qui vous dira où PHP cherche des fichiers cert. Et il y a ce paramètre, qui indiquera à file_get_contents() où chercher les fichiers cert. Peut-être que les deux vont marcher. J'ai préféré le paramètre. (Par rapport à la solution mentionnée ci-dessus).

donc c'est maintenant mon code PHP

$arrContextOptions=array(
    "ssl"=>array(
        "cafile" => "/Applications/XAMPP/xamppfiles/share/openssl/certs/chain.pem",
        "verify_peer"=> true,
        "verify_peer_name"=> true,
    ),
);

$response = file_get_contents($myHttpsURL, 0, stream_context_create($arrContextOptions));

C'est tout. file_get_contents() fonctionne à nouveau. Sans bouclage et avec un peu de chance sans failles de sécurité.

2
répondu n.r. 2017-10-14 11:56:26

après avoir été victime de ce problème sur centOS après avoir mis à jour PHP5.6 j'ai trouvé une solution qui a fonctionné pour moi.

Obtenir le bon répertoire pour votre certs pour être placé par défaut avec cette

php -r 'print_r(openssl_get_cert_locations());' | grep '\[default_cert_file\]' | awk '{print }'

puis utilisez ceci pour obtenir le cert et le mettre dans l'emplacement par défaut trouvé à partir du code ci-dessus

wget http://curl.haxx.se/ca/cacert.pem -O <default location>
2
répondu Edward DiGirolamo 2018-01-12 15:33:39

concernant des erreurs similaires à

[11-May-2017 19:19:13 America/Chicago] avertissement PHP: file_get_contents(): l'opération SSL a échoué avec le code 1. Messages d'erreur OpenSSL: erreur: 14090086: routines SSL: ssl3_get_server_certificate: certificat vérifier échoué

avez-vous vérifié les permissions du cert et les répertoires référencés par openssl?

Vous pouvez le faire

var_dump(openssl_get_cert_locations());

pour obtenir quelque chose similaire à ce

array(8) {
  ["default_cert_file"]=>
  string(21) "/usr/lib/ssl/cert.pem"
  ["default_cert_file_env"]=>
  string(13) "SSL_CERT_FILE"
  ["default_cert_dir"]=>
  string(18) "/usr/lib/ssl/certs"
  ["default_cert_dir_env"]=>
  string(12) "SSL_CERT_DIR"
  ["default_private_dir"]=>
  string(20) "/usr/lib/ssl/private"
  ["default_default_cert_area"]=>
  string(12) "/usr/lib/ssl"
  ["ini_cafile"]=>
  string(0) ""
  ["ini_capath"]=>
  string(0) ""
}

ce problème m'a frustré pendant un moment, jusqu'à ce que je réalise que mon dossier" certs " avait 700 permissions, alors qu'il aurait dû avoir 755 permissions. Rappelez-vous, ce n'est pas le dossier pour les clés, mais les certificats. Je recommande la lecture de ce lien sur les permissions ssl.

une Fois que j'ai fait

chmod 755 certs

le problème a été réglé, du moins pour moi de toute façon.

1
répondu Aleks 2017-05-12 00:46:15

j'ai eu le même problème pour une autre page sécurisée en utilisant wget ou file_get_contents . Beaucoup de recherche (y compris certaines des réponses à cette question) a abouti à une solution simple-installation Curl et PHP-Curl-si j'ai bien compris, Curl a la racine CA pour Comodo qui a résolu le problème

installer Curl et PHP-Curl addon, puis redémarrer Apache

sudo apt-get install curl
sudo apt-get install php-curl
sudo /etc/init.d/apache2 reload

tout fonctionne maintenant.

0
répondu Aubs 2017-12-31 13:31:56