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.
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; ?>
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.
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
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.
si votre version PHP est 5, essayez d'installer cURL en tapant la commande suivante dans le terminal:
sudo apt-get install php5-curl
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.
la suite des étapes ci-dessous va corriger cette question,
- Téléchargez le certificat CA À partir de ce lien: https://curl.haxx.se/ca/cacert.pem
- trouver et ouvrir php.ini
- rechercher
curl.cainfo
et coller le chemin absolu où vous avez télécharger le certificat.curl.cainfo ="C:\wamp\htdocs\cert\cacert.pem"
- redémarrer WAMP / XAMPP (apache server).
- Il fonctionne!
espère que ça aide !!
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.
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);
}
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
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é.
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>
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.
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.