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. Donc 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: Routines SSL: SSL3_GET_SERVER_CERTIFICATE: la vérification du certificat a échoué dans ... php sur la ligne 2
- Attention: file_get_contents (): Impossible d'activer la crypto dans ... php sur la ligne 2
- Attention: 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
): échec de l'ouverture du flux: échec de l'opération dans ... php sur la ligne 2
Nous utilisons un serveur Gentoo. Nous avons récemment mis à niveau vers la version 5.6 de PHP. C'est après la mise à jour que ce problème est apparu.
J'ai trouvé quand je remplace le service REST par une adresse comme https://www.google.com
; ma page fonctionne très bien.
Dans une tentative précédente, j'ai défini “verify_peer”=>false
et transmis cela en argument à file_get_contents, comme décrit ici: file_get_contents ignorant verify_peer => false? Mais comme l'écrivain l'a noté; cela n'a fait aucune différence.
J'ai demandé à l'un de nos administrateurs de serveur si ces lignes dans notre fichier php.ini existent:
- extension = php_openssl.dll
- allow_url_fopen = Activé
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 fichier php.ini.
J'ai également confirmé que cela allow_url_fopen
fonctionnait. En raison de la nature spécialisée de ce problème; Je ne trouve pas beaucoup d'informations pour m'aider. L'un de vous a-t-il rencontré quelque chose comme ça? Merci.
Réponses:
C'était un lien extrêmement utile à trouver:
http://php.net/manual/en/migration56.openssl.php
Un document officiel décrivant les modifications apportées à l'ouverture de ssl en PHP 5.6 D'ici, j'ai appris un autre paramètre que j'aurais dû mettre à 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; ?>
la source
file_get_contents($url, false, stream_context_create(array('ssl' => array('verify_peer' => false, 'verify_peer_name' => false))));
Vous ne devriez pas simplement désactiver la vérification. Vous devriez plutôt télécharger un bundle de certificats, peut-être que le bundle curl fera l'affaire?
Ensuite, il vous suffit de le mettre sur votre serveur Web, en donnant à l'utilisateur qui exécute php l'autorisation de lire le fichier. Ensuite, 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));
Espérons que le certificat racine du site auquel vous essayez d'accéder se trouve dans le bundle curl. Si ce n'est pas le cas, cela ne fonctionnera toujours pas tant que vous n'aurez pas obtenu le certificat racine du site et l'avez mis dans votre fichier de certificat.
la source
stream_context_set_default
qui peut être utilisée pour que vous n'ayez pas à la passer dans file_get_contents à chaque foisJ'ai corrigé cela en m'assurant que OpenSSL était installé sur ma machine, puis en l'ajoutant à mon php.ini:
la source
cert.pem
fichier et définiphp.ini
comme ceci, et cela a fonctionné:openssl.cafile=D:\Tools\GnuWin32\bin\cacert.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; }
Ensuite, utilisez simplement
file_get_contents_curl
au lieu defile_get_contents
chaque fois que vous appelez une URL commençant par https.la source
Pour moi, j'utilise PHP 5.6. L'extension openssl doit être activée et lors de l'appel de google map api verify_peer make false Le code ci-dessous fonctionne pour moi.
<?php $arrContextOptions=array( "ssl"=>array( "verify_peer"=>false, "verify_peer_name"=>false, ), ); $url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" . $latitude . "," . $longitude . "&sensor=false&key=" . Yii::$app->params['GOOGLE_API_KEY']; $data = file_get_contents($url, false, stream_context_create($arrContextOptions)); echo $data; ?>
la source
Si votre version PHP est 5, essayez d'installer cURL en tapant la commande suivante dans le terminal:
la source
cURL
.sudo port install php70-curl
Vous devez essentiellement définir la variable d'environnement SSL_CERT_FILE sur le 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 source
les étapes suivantes résoudront ce problème,
curl.cainfo
et collez le chemin absolu où vous avez téléchargé le certificat.curl.cainfo ="C:\wamp\htdocs\cert\cacert.pem"
J'espère que ça t'as aidé !!
la source
Je voulais juste ajouter à cela car j'ai rencontré le même problème et rien de ce que je pourrais trouver n'importe où ne fonctionnerait (par exemple, télécharger le fichier cacert.pem, configurer cafile dans php.ini, etc.)
Si vous utilisez NGINX et que votre certificat SSL est livré avec un "certificat intermédiaire", vous devez combiner le fichier de certificat intermédiaire avec votre fichier principal "mydomain.com.crt" et cela devrait fonctionner. Apache a un paramètre spécifique pour les certificats intermédiaires, mais NGINX ne l'a pas donc il doit être dans le même fichier que votre certificat régulier.
la source
La raison de cette erreur est que PHP n'a pas de liste d'autorités de certification de confiance.
PHP 5.6 et les versions ultérieures essaient de charger automatiquement les autorités de certification approuvées par le système. Les problèmes peuvent être résolus. Voir http://php.net/manual/en/migration56.openssl.php pour plus d'informations.
PHP 5.5 et les versions antérieures sont vraiment difficiles à configurer correctement car vous devez spécifier manuellement le bundle 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 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); }
la source
Eu la même erreur avec PHP 7 sur XAMPP et OSX.
La réponse mentionnée ci-dessus dans https://stackoverflow.com/ est bonne, mais elle n'a pas complètement résolu le problème pour moi. J'ai dû fournir la chaîne de certificats complète pour que file_get_contents () fonctionne à nouveau. Voilà comment je l'ai fait:
Obtenir le certificat racine / intermédiaire
Tout d'abord, je devais comprendre quelle était la racine et le certificat intermédiaire.
Le moyen le plus pratique est peut-être un outil de certification en ligne 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 j'ai à faire est de rechercher les deux sur Internet. Dans mon cas, c'est la racine:
thawte DV SSL SHA256 CA
Et cela mène à son url thawte.com . J'ai donc simplement mis ce certificat dans un fichier texte et j'ai fait de même pour l'intermédiaire. Terminé.
Obtenez le certificat d'hôte
La prochaine chose que je devais faire est de télécharger mon certificat de serveur. Sur 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 dans un seul fichier. (Peut-être qu'il est bon de les mettre dans un dossier, je les ai juste fusionnés en un seul fichier) Vous pouvez le faire comme ceci:
dire à PHP où trouver la chaîne
Il y a cette fonction pratique openssl_get_cert_locations () qui vous dira où PHP recherche les fichiers cert. Et il y a ce paramètre, qui dira à file_get_contents () où chercher les fichiers cert. Peut-être que les deux méthodes fonctionneront. J'ai préféré la méthode des paramètres. (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 CURL et espérons-le sans failles de sécurité.
la source
chain.pem
? C'est çachain.crt
?Après avoir été victime de ce problème sur centOS après la mise à jour de php vers php5.6, j'ai trouvé une solution qui fonctionnait pour moi.
Obtenez le répertoire correct pour vos certificats à placer par défaut avec ceci
php -r 'print_r(openssl_get_cert_locations()["default_cert_file"]);'
Ensuite, utilisez ceci pour obtenir le certificat 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>
la source
J'ai eu le même problème ssl sur ma machine de développement (php 7, xampp sous Windows) avec un certificat auto-signé essayant d'ouvrir un fichier " https: // localhost / ...". De toute évidence, l'assembly du certificat racine (cacert.pem) ne fonctionnait pas. Je viens de copier manuellement le code du fichier apache server.crt-File dans le cacert.pem téléchargé et j'ai fait l'entrée openssl.cafile = path / to / cacert.pem dans php.ini
la source
Une autre chose à essayer est de réinstaller
ca-certificates
comme détaillé ici .# yum reinstall ca-certificates ... # update-ca-trust force-enable # update-ca-trust extract
Et une autre chose à essayer est d'autoriser explicitement le certificat du site en question comme décrit ici (surtout si le site est votre propre serveur et que vous avez déjà le .pem à portée de main).
# cp /your/site.pem /etc/pki/ca-trust/source/anchors/ # update-ca-trust extract
Je tombais sur cette erreur SO exacte après la mise à niveau vers PHP 5.6 sur CentOS 6 en essayant d'accéder au serveur lui-même qui a un certificat de sécurité à bas prix qu'il fallait peut-être mettre à jour, mais au lieu de cela, j'ai installé un certificat letsencrypt et avec ces deux étapes ci-dessus, il l'a fait l'astuce. Je ne sais pas pourquoi la deuxième étape était nécessaire.
Commandes utiles
Voir la version openssl:
# openssl version OpenSSL 1.0.1e-fips 11 Feb 2013
Afficher les paramètres actuels de PHP cli ssl:
# php -i | grep ssl openssl Openssl default config => /etc/pki/tls/openssl.cnf openssl.cafile => no value => no value openssl.capath => no value => no value
la source
Concernant les erreurs similaires à
Avez-vous vérifié les autorisations du certificat et des répertoires référencés par openssl?
Tu peux le faire
Pour obtenir quelque chose de similaire
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 certain temps, jusqu'à ce que je réalise que mon dossier «certs» avait 700 autorisations, alors qu'il aurait dû en avoir 755. N'oubliez pas que ce n'est pas le dossier des clés mais des certificats. Je recommande de lire ce lien sur les autorisations SSL.
Une fois que j'ai fait
chmod 755 certs
Le problème a été résolu, du moins pour moi en tout cas.
la source
J'ai eu le même problème pour une autre page sécurisée lors de l'utilisation de
wget
oufile_get_contents
. De nombreuses recherches (y compris certaines des réponses à cette question) ont abouti à une solution simple - installer Curl et PHP-Curl - Si j'ai bien compris, Curl a la racine CA pour Comodo qui a résolu le problèmeInstallez Curl et l'addon PHP-Curl, puis redémarrez Apache
Tout fonctionne maintenant.
la source