Erreur cURL 60: certificat SSL: impossible d'obtenir le certificat d'émetteur local

232

J'utilise WAMP sur un environnement de développement local et j'essaie de débiter une carte de crédit mais j'obtiens le message d'erreur:

Erreur cURL 60: problème de certificat SSL: impossible d'obtenir le certificat d'émetteur local

J'ai beaucoup cherché sur Google et beaucoup de gens suggèrent de télécharger ce fichier: cacert.pem , de le mettre quelque part et de le référencer dans mon php.ini. C'est la partie de mon php.ini:

curl.cainfo = "C:\Windows\cacert.pem"

Pourtant, même après avoir redémarré mon serveur plusieurs fois et changé de chemin, j'obtiens le même message d'erreur.

J'utilise WAMP des modules Apache et ai le ssl_module activé. Et à partir des extensions PGP, j'ai php_curl activé.

Toujours le même message d'erreur. Pourquoi cela se produit-il?

Maintenant, je suis ce correctif: Comment corriger l'erreur PHP CURL 60 SSL

Ce qui suggère que j'ajoute ces lignes à mes options cURL:

curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, true);

Où puis-je ajouter des options à mon cURL? Apparemment pas via la ligne de commande, car ma CLI ne trouve pas la commande "curl_setopt"

ÉDITER

Voici le code que j'utilise:

public function chargeStripe()
{
    $stripe = new Stripe;
    $stripe = Stripe::make(env('STRIPE_PUBLIC_KEY'));

    $charge = $stripe->charges()->create([
        'amount'   => 2900,
        'customer' => Input::get('stripeEmail'),
        'currency' => 'EUR',
    ]);

    dd($charge);

    // echo $charge[Input::get('stripeToken')];


    return Redirect::route('step1');
}
Amour et bonheur
la source
En supposant qu'il n'y ait aucun problème avec votre code, il pourrait s'agir de votre pare-feu. Essayez de désactiver votre pare-feu pour tester.
Waqar ul islam
ne vous ai-je pas répondu ici à cette question ? :)
Limon Monte
@limonte possible, a dû changer de projet et a probablement le même problème avec le nouveau projet. Reviendra au problème de guzzle et c'est peut-être la même solution. brb
LoveAndHappiness
1
Avez-vous essayé la dernière version de stripe? Je vois un message de validation qui a changé quelque chose à voir avec les certificats
thelastshadow
1
@LoveAndHappiness avez-vous la solution à ce problème? Je fais face à la même erreur avec la bande. Veuillez me faire savoir si vous avez une solution.
Dev

Réponses:

516

Solution de travail en supposant que votre Windows utilise XAMPP:

Serveur XAMPP

  1. Similaire pour un autre environnement
    • télécharger et extraire pour cacert.pem ici (un format de fichier / données propre)

https://curl.haxx.se/docs/caextract.html

  1. Mettez-le ici dans le répertoire suivant.

C: \ xampp \ php \ extras \ ssl \ cacert.pem

  1. Dans votre php.ini mettez cette ligne dans cette section ("c: \ xampp \ php \ php.ini"):
;;;;;;;;;;;;;;;;;;;;
; php.ini Options  ;
;;;;;;;;;;;;;;;;;;;;

curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
  1. Redémarrez votre serveur web / apache

  2. Problème résolu!

(Référence: https://laracasts.com/discuss/channels/general-discussion/curl-error-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate )

Fumier
la source
6
Ce message arrive à cause de votre version PHP. S'il est supérieur à PHP 5.5, cette erreur est due à la nouvelle fonctionnalité de PHP 5.6. PHP 5.6 vérifie les certificats si vous utilisez cURL.
UWU_SANDUN
9
Merci d'avoir répondu! Bien que je recommande d'utiliser le cacert.pem de la page officielle de curl: curl.haxx.se/docs/caextract.html
dieBeiden
6
Je voulais juste signaler à quiconque ne peut pas faire fonctionner cela - j'ai utilisé des barres obliques curl.cainfo = "C:/cacert.pem"et j'ai également dû redémarrer mon ordinateur pour le faire fonctionner. Le redémarrage du serveur Web n'était pas suffisant. J'espère que cela aide:]
space_food_
1
et n'oubliez pas de décommenter curl.cainfo(facepalm)
Edmund Sulzanok
A fonctionné comme un charme! Merci
Jack
57

Attention aux utilisateurs de Wamp / Wordpress / windows. J'ai eu ce problème pendant des heures et même la bonne réponse ne le faisait pas pour moi, car je modifiais le mauvais fichier php.ini parce que la question avait été répondue à XAMPP et non aux utilisateurs de WAMP, même si la question était pour WAMP.

voici ce que j'ai fait

Téléchargez l' ensemble de certificats.

Mettez-le à l'intérieur de C:\wamp64\bin\php\your php version\extras\ssl

Assurez-vous que le fichier mod_ssl.soest à l'intérieur deC:\wamp64\bin\apache\apache(version)\modules

Activer mod_ssldans httpd.confle répertoire ApacheC:\wamp64\bin\apache\apache2.4.27\conf

Activer php_openssl.dlldans php.ini. Sachez que mon problème était que j'avais deux fichiers php.ini et que je devais le faire dans les deux. Le premier peut être situé à l'intérieur de l'icône de votre barre des tâches WAMP ici.

entrez la description de l'image ici

et l'autre est situé dans C:\wamp64\bin\php\php(Version)

trouver l'emplacement des deux php.inifichiers et trouver la ligne curl.cainfo =et lui donner un chemin comme celui-ci

curl.cainfo = "C:\wamp64\bin\php\php(Version)\extras\ssl\cacert.pem"

Maintenant, enregistrez les fichiers et redémarrez votre serveur et vous devriez être prêt à partir

Rami Nour
la source
C'est moins que vous deviez faire les deux php.ini que celui que vous avez l'intention d'utiliser: si vous utilisez apache comme client SAPI, modifiez celui du répertoire apache et / ou modifiez celui du client dir si vous prévoyez d'utiliser php.exe comme SAPI.
Fabien Haddadi
3
"Je dois faire cela dans les deux" est la note clé. Merci
Jaroslav Klimčík
1
Cela fonctionne pour Laravel 5.5 avec "guzzlehttp / guzzle": "^ 6.3". Serveur Wamp 3.1.3. Php 7.1 *
Deepesh Thapa
cela a fonctionné. Merci
user4906240
Merci d'avoir répondu pour wamp
altoids
46

Si vous utilisez PHP 5.6 avec Guzzle, Guzzle est passé à l'utilisation de la détection automatique des bibliothèques PHP pour les certificats plutôt que de son processus ( ref ). PHP décrit les changements ici .

Découvrir où PHP / Guzzle recherche des certificats

Vous pouvez effectuer un vidage là où PHP cherche en utilisant:

 var_dump(openssl_get_cert_locations());

Obtenir un ensemble de certificats

Pour les tests OS X, vous pouvez utiliser homebrew pour installer openssl brew install opensslpuis utiliser openssl.cafile=/usr/local/etc/openssl/cert.pemdans vos paramètres php.ini ou Zend Server (sous OpenSSL).

Un paquet de certificats est également disponible auprès de curl / Mozilla sur le site Web de curl: https://curl.haxx.se/docs/caextract.html

Dire à PHP où se trouvent les certificats

Une fois que vous avez un bundle, placez-le là où PHP regarde déjà (que vous avez découvert ci-dessus) ou mettez-le openssl.cafileà jour dans php.ini. ( En règle générale, /etc/php.iniou , /etc/php/7.0/cli/php.iniou /etc/php/php.inisur Unix.)

Loren
la source
3
OUI. Après avoir vu trop de gens suggérer l'approche manifestement erronée de la rétrogradation par plusieurs numéros de version, cela représente la bonne approche à mon humble avis. J'avais suivi les conseils des autres sur le café, mais je n'avais aucun moyen de tester pourquoi il ne se chargeait toujours pas. Cette fonction openssl_get_cert_locations () a vraiment fait le travail pour identifier mon problème. Merci!
Web and Flow
1
Merci d'avoir fourni openssl_get_cert_locations, cela a facilité le débogage. On dirait que WAMP utilise un fichier ini différent pour php apache que pour php console. Dans mon cas, j'ai dû ajouter openssl.cafile="c:/_/cacert.pem"du php sur console. La dernière fois, lors de son utilisation via Apache, j'avais besoin curl.cainfo="c:/_/cacert.pem"de le faire fonctionner.
psycho brm
16

Guzzle, qui est utilisé par cartalyst / stripe , fera ce qui suit pour trouver une archive de certificat appropriée pour comparer un certificat de serveur:

  1. Vérifiez s'il openssl.cafileest défini dans votre fichier php.ini.
  2. Vérifiez s'il curl.cainfoest défini dans votre fichier php.ini.
  3. Vérifier s'il /etc/pki/tls/certs/ca-bundle.crtexiste (Red Hat, CentOS, Fedora; fourni par le paquet ca-certificats)
  4. Vérifier s'il /etc/ssl/certs/ca-certificates.crtexiste (Ubuntu, Debian; fourni par le paquet ca-certificats)
  5. Vérifier s'il /usr/local/share/certs/ca-root-nss.crtexiste (FreeBSD; fourni par le paquet ca_root_nss)
  6. Vérifiez si /usr/local/etc/openssl/cert.pem(OS X; fourni par homebrew)
  7. Vérifier s'il C:\windows\system32\curl-ca-bundle.crtexiste (Windows)
  8. Vérifier s'il C:\windows\curl-ca-bundle.crtexiste (Windows)

Vous voudrez vous assurer que les valeurs des deux premiers paramètres sont correctement définies en effectuant un test simple:

echo "openssl.cafile: ", ini_get('openssl.cafile'), "\n";
echo "curl.cainfo: ", ini_get('curl.cainfo'), "\n";

Vous pouvez également essayer d'écrire le fichier aux emplacements indiqués par # 7 ou # 8.

Jack
la source
13

Si vous ne pouvez pas modifier php.ini, vous pouvez également pointer vers le fichier cacert.pem à partir d'un code comme celui-ci:

$http = new GuzzleHttp\Client(['verify' => '/path/to/cacert.pem']);
$client = new Google_Client();
$client->setHttpClient($http);
mvandillen
la source
8

Ce que j'ai fait a été utilisé var_dump(openssl_get_cert_locations()); die;dans n'importe quel script php, ce qui m'a donné les informations sur les valeurs par défaut que mon php local utilisait:

array (size=8)
  'default_cert_file' => string 'c:/openssl-1.0.1c/ssl/cert.pem' (length=30)
  'default_cert_file_env' => string 'SSL_CERT_FILE' (length=13)
  'default_cert_dir' => string 'c:/openssl-1.0.1c/ssl/certs' (length=27)
  'default_cert_dir_env' => string 'SSL_CERT_DIR' (length=12)
  'default_private_dir' => string 'c:/openssl-1.0.1c/ssl/private' (length=29)
  'default_default_cert_area' => string 'c:/openssl-1.0.1c/ssl' (length=21)
  'ini_cafile' => string 'E:\xampp\php\extras\ssl\cacert.pem' (length=34)
  'ini_capath' => string '' (length=0)

Comme vous pouvez le constater, j'ai défini l'ini_cafile ou l'option ini curl.cainfo. Mais dans mon cas, curl essaierait d'utiliser le "default_cert_file" qui n'existait pas.

J'ai copié le fichier de https://curl.haxx.se/ca/cacert.pem dans l'emplacement de "default_cert_file" (c: /openssl-1.0.1c/ssl/cert.pem) et j'ai pu l'obtenir travailler.

C'était la seule solution pour moi.

George Donev
la source
J'ai un problème similaire et mon emplacement est quelque chose comme c: /usr/local/ssl/cert.pem mais cet emplacement n'existe pas, faites-vous ce qu'il pourrait être, en outre le même projet est utilisé par ma coluge sur une machine mac pourrait c'est la raison, j'ai essayé tout le reste, c'est-à-dire l'ajout d'un emplacement de cert dans le fichier .ini mais cela ne fonctionne pas, il semble que votre solution devrait fonctionner comme il est logique mais ne peut pas changer cet emplacement et ne peut pas mettre de certificat dans un endroit qui n'existe pas.
AbdulMueed
Vous pouvez essayer de créer les dossiers et de mettre le certificat à votre chemin spécifié?
George Donev
7

J'ai eu ce problème un jour à l'improviste, lorsqu'un script Guzzle (5) tentait de se connecter à un hôte via SSL. Bien sûr, je pourrais désactiver l'option VERIFY dans Guzzle / Curl, mais ce n'est clairement pas la bonne façon de procéder.

J'ai essayé tout ce qui est répertorié ici et dans des threads similaires, puis je suis finalement allé au terminal avec openssl pour tester le domaine avec lequel j'essayais de me connecter:

openssl s_client -connect example.com:443 

... et a reçu les premières lignes indiquant:

CONNECTED(00000003)
depth=0 CN = example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = example.com
verify error:num=21:unable to verify the first certificate
verify return:1 

... alors que tout fonctionnait bien lorsque vous essayiez d'autres destinations (par exemple: google.com, etc.)

Cela m'a incité à contacter le domaine auquel j'avais essayé de me connecter, et en effet, ils avaient un problème sur LEUR FIN qui s'était glissé. Il a été résolu et mon script a recommencé à fonctionner.

Donc ... si vous vous arrachez les cheveux, donnez à openssl un coup de feu et voyez s'il y a quelque chose avec la réponse de l'emplacement que vous essayez de connecter. Peut-être que le problème n'est pas si «local» après tout parfois.

Nation Daydream
la source
6

J'ai trouvé une solution qui a fonctionné pour moi. J'ai rétrogradé de la dernière version à la version ~ 4.0 et cela a fonctionné.

Dans composer.json, ajoutez "guzzlehttp / guzzle": "~ 4.0"

J'espère que cela aide quelqu'un

Iruku Kagika
la source
Cela vous empêchera également d'utiliser des fonctionnalités de la version 5/6. Au lieu de cela, définissez la vérification sur false dans un tableau de paramètres (3e paramètre de la méthode de demande): $ client-> request ('GET', '/', ['verify' => false]);
S ..
3

Assurez-vous que vous ouvrez le php.inifichier directement par votre explorateur de fenêtres. (dans mon cas:) C:\DevPrograms\wamp64\bin\php\php5.6.25.

N'utilisez pas le raccourci vers php.inidans le menu de l'icône Wamp / Xamp dans la barre d'état système. Ce raccourci ne fonctionne pas dans ce cas.

Modifiez ensuite cela php.ini:

curl.cainfo ="C:/DevPrograms/wamp64/bin/php/cacert.pem" 

et

openssl.cafile="C:/DevPrograms/wamp64/bin/php/cacert.pem"

Après avoir enregistré, php.inivous n'avez pas besoin de "Redémarrer tous les services" dans l'icône Wamp ou de fermer / rouvrir CMD.

Quang Nguyen Tri
la source
2

As-tu essayé..

curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);

Si vous utilisez une source fiable, vous n'avez sans doute pas besoin de vérifier le certificat SSL.

Mike Miller
la source
2

J'ai passé trop de temps à comprendre ce problème pour moi.

J'avais PHP version 5.5 et je devais passer à 5.6.

Dans les versions <5.6, Guzzle utilisera son propre fichier cacert.pem, mais dans les versions supérieures de PHP, il utilisera le fichier cacert.pem du système.

J'ai également téléchargé le fichier ici https://curl.haxx.se/docs/caextract.html et l' ai placé dans php.ini.

Réponse trouvée dans le fichier Guzzles StreamHandler.php https://github.com/guzzle/guzzle/blob/0773d442aa96baf19d7195f14ba6e9c2da11f8ed/src/Handler/StreamHandler.php#L437

        // PHP 5.6 or greater will find the system cert by default. When
        // < 5.6, use the Guzzle bundled cacert.
Marko Milivojevic
la source
2

Toutes les réponses sont correctes ; mais la chose la plus importante est que vous devez trouver le bon fichier php.ini. vérifier cette commande dans cmd "php --ini" n'est pas la bonne réponse pour trouver le bon fichier php.ini.

si vous éditez

curl.cainfo ="PATH/cacert.pem"

et vérifie

var_dump(openssl_get_cert_locations()); 

alors curl.cainfo devrait avoir une valeur. sinon, ce n'est pas le bon fichier php.ini;

* Je vous recommande de rechercher * .ini dans wamp / bin ou xxamp / bin ou tout serveur que vous utilisez et de les modifier un par un et de le vérifier. *

Mohsen Molaei
la source
1

Je viens de rencontrer ce même problème avec le framework PHP Laravel 4 qui utilise le guzzlehttp/guzzlepackage Composer. Pour une raison quelconque, le certificat SSL pour mailgun a soudainement cessé de valider et j'ai reçu le même message "erreur 60".

Si, comme moi, vous êtes sur un hébergement mutualisé sans accès php.ini, les autres solutions ne sont pas possibles. Dans tous les cas, Guzzle a ce code d'initialisation client qui annulerait très probablement les php.inieffets:

// vendor/guzzlehttp/guzzle/src/Client.php
    $settings = [
        'allow_redirects' => true,
        'exceptions'      => true,
        'decode_content'  => true,
        'verify'          => __DIR__ . '/cacert.pem'
    ];

Ici, Guzzle force l'utilisation de son propre fichier interne cacert.pem, qui est probablement maintenant obsolète, au lieu d'utiliser celui fourni par l'environnement de cURL . Changer cette ligne (sur Linux au moins) configure Guzzle pour utiliser la logique de vérification SSL par défaut de cURL et a résolu mon problème:

        'verify'          => true

Vous pouvez également définir cette option falsesi vous ne vous souciez pas de la sécurité de votre connexion SSL, mais ce n'est pas une bonne solution.

Étant donné que les fichiers vendorne sont pas destinés à être falsifiés, une meilleure solution serait de configurer le client Guzzle lors de l'utilisation, mais cela était tout simplement trop difficile à faire dans Laravel 4.

J'espère que cela économisera à quelqu'un d'autre quelques heures de débogage ...

bernie
la source
1

Cela pourrait être un cas périphérique, mais dans mon cas, le problème n'était pas la configuration client (que j'avais déjà curl.cainfoconfigurée dans php.ini), mais plutôt le serveur distant qui n'était pas configuré correctement:

Il n'a envoyé aucun certificat intermédiaire dans la chaîne. Il n'y a pas eu d'erreur lors de la navigation sur le site avec Chrome, mais avec PHP, j'ai eu l'erreur suivante.

erreur cURL 60

Après avoir inclus les certificats intermédiaires dans la configuration du serveur Web distant, cela a fonctionné.

Vous pouvez utiliser ce site pour vérifier la configuration SSL de votre serveur:

https://whatsmychaincert.com/

Tobias K.
la source
1

quand je cours 'var_dump(php_ini_loaded_file());' j'obtiens cette sortie sur ma page 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' (length=50)'

et pour que php charge mon fichier cert, j'ai dû éditer le php.ini dans ce chemin 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' et ajouter openssl.cafile="C:/Development/bin/php/php7.2.4/extras/ssl/cacert.pem"où j'avais téléchargé et placer mon fichier cert depuis https://curl.haxx.se/docs/caextract.html

suis sur windows 10, en utilisant drupal 8, wamp et php7.2.4

Nicolas
la source
0

J'ai une bonne solution à ce problème, essayons de comprendre la cause première de ce problème. Ce problème survient lorsque ssl de serveurs distants ne peut pas être vérifié à l'aide de certificats racine dans le magasin de certificats de votre système ou ssl distant n'est pas installé avec des certificats de chaîne. Si vous avez un système Linux avec un accès root ssh, alors dans ce cas, vous pouvez essayer de mettre à jour votre magasin de certificats avec la commande ci-dessous:

update-ca-certificates

Si cela ne fonctionne toujours pas, vous devez ajouter le certificat racine et intermédiaire du serveur distant dans votre magasin de certificats. Vous pouvez télécharger les certificats racine et intermédiaires et les ajouter dans le répertoire / usr / local / share / ca-certificats , puis exécuter la commande update-ca-certificates. Cela devrait faire l'affaire. De même pour les fenêtres, vous pouvez rechercher comment ajouter des certificats racine et intermédiaire.

L'autre façon de résoudre ce problème consiste à demander à l'équipe du serveur distant d'ajouter le certificat SSL en tant que paquet de certificats racine de domaine, de certificats intermédiaires et de certificats racine.

prasoon
la source
-1

Comme vous utilisez Windows, je pense que votre séparateur de chemin est '\' (et '/' sous Linux). Essayez d'utiliser la constante DIRECTORY_SEPARATOR. Votre code sera plus portable.

Essayer:

curl_setopt($process, CURLOPT_CAINFO, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cacert.pem');

EDIT: et écrivez le chemin complet. J'ai eu quelques problèmes avec les chemins relatifs (peut-être que curl est exécuté à partir d'un autre répertoire de base?)

C Würtz
la source
1
Cela ne ferait aucune différence, car les paramètres cURL réels sont hors de votre contrôle lorsque vous utilisez cette bibliothèque Stripe particulière.
Ja͢ck
-1

si vous utilisez WAMP, vous devez également ajouter la ligne de certificat dans php.ini pour Apache (en plus du fichier php.ini par défaut):

[curl]
curl.cainfo = C:\your_location\cacert.pem

fonctionne pour php5.3 +

bob
la source
Oui! Veillez à modifier les fichiers php.ini de la version apache et php. Pour les utilisateurs de WAMP, cette réponse était la seule à résoudre mon problème: stackoverflow.com/questions/28858351/…
MavBzh