cURL-Fehler 60: SSL-Zertifikat: Lokales Ausstellerzertifikat kann nicht abgerufen werden


232

Ich verwende WAMP in einer lokalen Entwicklungsumgebung und versuche, eine Kreditkarte zu belasten, erhalte jedoch die folgende Fehlermeldung:

cURL-Fehler 60: SSL-Zertifikatproblem: Lokales Ausstellerzertifikat kann nicht abgerufen werden

Ich habe viel bei Google gesucht und viele Leute schlagen vor, diese Datei herunterzuladen: cacert.pem , sie irgendwo abzulegen und in meiner php.ini zu referenzieren. Dies ist der Teil in meiner php.ini:

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

Selbst nach mehrmaligem Neustart meines Servers und Ändern des Pfads wird dieselbe Fehlermeldung angezeigt.

Ich verwende WAMP aus den Apache-Modulen und habe das ssl_module aktiviert. Und von den PGP-Erweiterungen habe ich php_curl aktiviert.

Immer noch die gleiche Fehlermeldung. Warum passiert das?

Jetzt folge ich diesem Fix: So beheben Sie PHP CURL Fehler 60 SSL

Was darauf hindeutet, dass ich diese Zeilen zu meinen cURL-Optionen hinzufüge:

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

Wo füge ich meiner cURL Optionen hinzu? Anscheinend nicht über die Befehlszeile, da meine CLI den Befehl "curl_setopt" nicht findet.

BEARBEITEN

Dies ist der Code, den ich ausführe:

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');
}

Vorausgesetzt, es gibt keine Probleme mit Ihrem Code, könnte es sich um Ihre Firewall handeln. Deaktivieren Sie zum Testen Ihre Firewall.
Waqar ul Islam

Habe ich dir hier keine Antwort auf diese Frage gegeben ? :)
Limon Monte

@limonte möglich, musste Projekte wechseln und habe wahrscheinlich das gleiche Problem mit dem neuen Projekt. Wechselt zurück zum Fressproblem und vielleicht ist es das gleiche Update. brb
LoveAndHappiness

1
Haben Sie die neueste Version von Stripe ausprobiert? Ich sehe eine Commit-Nachricht, die etwas mit Zertifikaten zu tun hat ... github.com/stripe/stripe-php/commit/…
thelastshadow

1
@LoveAndHappiness hast du die Lösung für dieses Problem? Ich habe den gleichen Fehler mit Streifen. Bitte lassen Sie mich wissen, wenn Sie eine Lösung haben.
Dev

Antworten:


515

Arbeitslösung unter der Annahme, dass Sie unter Windows XAMPP verwenden:

XAMPP-Server

  1. Ähnliches gilt für andere Umgebungen
    • Laden Sie hier cacert.pem herunter und extrahieren Sie es (ein sauberes Dateiformat / Daten)

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

  1. Legen Sie es hier in das folgende Verzeichnis.

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

  1. Fügen Sie in Ihrer php.ini diese Zeile in diesen Abschnitt ein ("c: \ xampp \ php \ php.ini"):
;;;;;;;;;;;;;;;;;;;;
; php.ini Options  ;
;;;;;;;;;;;;;;;;;;;;

curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
  1. Starten Sie Ihren Webserver / Apache neu

  2. Problem gelöst!

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


6
Diese Nachricht kommt wegen Ihrer PHP-Version. Wenn es von PHP 5.5 höher ist, tritt dieser Fehler aufgrund der neuen Funktion von PHP 5.6 auf. PHP 5.6 prüft Zertifikate, wenn Sie cURL verwenden.
UWU_SANDUN

9
Danke für die Antwort! Obwohl ich empfehlen würde, die cacert.pem von der offiziellen Curl-Seite zu verwenden: curl.haxx.se/docs/caextract.html
dieBeiden

6
Ich wollte nur auf jemanden hinweisen, der dies nicht zum Laufen bringen kann - ich habe Schrägstriche verwendet curl.cainfo = "C:/cacert.pem"und musste auch meinen Computer neu starten, damit er funktioniert. Es reichte nicht aus, den Webserver neu zu starten. Hoffentlich hilft das:]
space_food_

1
und vergessen Sie nicht zu kommentieren curl.cainfo(Gesichtspalme)
Edmund Sulzanok

Lief wie am Schnürchen! Danke
Jack

54

Achtung Wamp / Wordpress / Windows-Benutzer. Ich hatte dieses Problem stundenlang und nicht einmal die richtige Antwort hat es für mich getan, weil ich die falsche php.ini-Datei bearbeitet habe, weil die Frage an XAMPP beantwortet wurde und nicht für WAMP-Benutzer, obwohl die Frage für WAMP war.

Hier ist was ich getan habe

Laden Sie die Zertifikatspaket .

Legen Sie es in C:\wamp64\bin\php\your php version\extras\ssl

Stellen Sie sicher, dass die Datei mod_ssl.so befindetC:\wamp64\bin\apache\apache(version)\modules

Aktivieren mod_sslinhttpd.conf innerhalb von Apache - VerzeichnisC:\wamp64\bin\apache\apache2.4.27\conf

Aktivieren php_openssl.dllin php.ini. Seien Sie sich bewusst, dass mein Problem darin bestand, dass ich zwei php.ini-Dateien hatte und dies in beiden tun muss. Das erste befindet sich hier in Ihrem WAMP-Taskleistensymbol.

Geben Sie hier die Bildbeschreibung ein

und der andere befindet sich in C:\wamp64\bin\php\php(Version)

Suchen Sie den Speicherort für beide php.iniDateien, suchen Sie die Zeile curl.cainfo =und geben Sie einen Pfad wie diesen an

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

Speichern Sie nun die Dateien und starten Sie Ihren Server neu. Sie sollten bereit sein


Es ist weniger so, dass Sie beide php.ini ausführen müssen als die, die Sie verwenden möchten: Wenn Sie Apache als SAPI-Client verwenden, ändern Sie die im Apache-Verzeichnis und / oder die im Client dir, wenn du vorhast, php.exe als SAPI zu verwenden.
Fabien Haddadi

3
"Ich muss das in beiden tun" ist der Grundton. Vielen Dank
Jaroslav Klimčík

1
Dies funktioniert für Laravel 5.5 mit "guzzlehttp / guzzle": "^ 6.3". Wamp-Server 3.1.3. Php 7.1 *
Deepesh Thapa

das hat funktioniert. Danke
user4906240

Vielen Dank für die Antwort für wamp
Altoids

46

Wenn Sie PHP 5.6 mit Guzzle verwenden, hat Guzzle die automatische Erkennung der PHP-Bibliotheken für Zertifikate anstelle des Prozesses ( ref ) verwendet. PHP beschreibt die Änderungen hier .

Finden Sie heraus, wo PHP / Guzzle nach Zertifikaten sucht

Sie können sichern, wo PHP sucht, indem Sie Folgendes verwenden:

 var_dump(openssl_get_cert_locations());

Ein Zertifikatspaket erhalten

Für OS X-Tests können Sie mit homebrew openssl installieren brew install opensslund dann openssl.cafile=/usr/local/etc/openssl/cert.pemin Ihren Einstellungen für php.ini oder Zend Server (unter OpenSSL) verwenden.

Ein Zertifikatspaket ist auch bei curl / Mozilla auf der curl-Website erhältlich: https://curl.haxx.se/docs/caextract.html

PHP mitteilen, wo sich die Zertifikate befinden

Sobald Sie ein Bundle haben, platzieren Sie es entweder dort, wo PHP bereits sucht (was Sie oben herausgefunden haben) oder aktualisieren Sie es openssl.cafilein der php.ini. ( Im Allgemeinen /etc/php.inioder /etc/php/7.0/cli/php.inioder /etc/php/php.iniauf Unix.)


3
JA. Nachdem zu viele Leute den offensichtlich falschen Ansatz des Downgrades um mehrere Versionsnummern vorgeschlagen haben, steht dies imho als der richtige Ansatz. Ich war den Ratschlägen anderer über das Café gefolgt, hatte aber keine Möglichkeit zu testen, warum es immer noch nicht geladen wurde. Diese Funktion openssl_get_cert_locations () hat wirklich dazu beigetragen, mein Problem zu identifizieren. Vielen Dank!
Web und Flow

1
Vielen Dank für die Bereitstellung openssl_get_cert_locations, es hat das Debuggen viel einfacher gemacht. Es sieht so aus, als ob WAMP für Apache PHP eine andere INI-Datei verwendet als für Console PHP. In meinem Fall musste ich openssl.cafile="c:/_/cacert.pem"für konsolenbasiertes PHP hinzufügen . Als ich es das letzte Mal über Apache verwendet habe, musste ich curl.cainfo="c:/_/cacert.pem"dafür sorgen, dass es funktioniert.
Psycho Brm

16

Guzzle, das von Cartalyst / Stripe verwendet wird , führt die folgenden Schritte aus , um ein geeignetes Zertifikatarchiv zu finden, anhand dessen ein Serverzertifikat überprüft werden kann:

  1. Überprüfen Sie, ob openssl.cafilein Ihrer php.ini-Datei festgelegt ist.
  2. Überprüfen Sie, ob curl.cainfoin Ihrer php.ini-Datei festgelegt ist.
  3. Überprüfen Sie, ob /etc/pki/tls/certs/ca-bundle.crtvorhanden (Red Hat, CentOS, Fedora; im Paket mit den Ca-Zertifikaten enthalten).
  4. Überprüfen Sie, ob es /etc/ssl/certs/ca-certificates.crtexistiert (Ubuntu, Debian; bereitgestellt durch das ca-certificates-Paket)
  5. Überprüfen Sie, ob /usr/local/share/certs/ca-root-nss.crt vorhanden (FreeBSD; bereitgestellt vom Paket ca_root_nss).
  6. Überprüfen Sie, ob /usr/local/etc/openssl/cert.pem(OS X; bereitgestellt von Homebrew)
  7. Überprüfen Sie, ob C:\windows\system32\curl-ca-bundle.crtvorhanden (Windows)
  8. Überprüfen Sie, ob C:\windows\curl-ca-bundle.crtvorhanden (Windows)

Sie sollten sicherstellen, dass die Werte für die ersten beiden Einstellungen richtig definiert sind, indem Sie einen einfachen Test durchführen:

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

Versuchen Sie alternativ, die Datei an die durch # 7 oder # 8 angegebenen Speicherorte zu schreiben.


12

Wenn Sie die php.ini nicht ändern können, können Sie auch aus folgendem Code auf die Datei cacert.pem verweisen:

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

8

Was ich getan habe, war die Verwendung var_dump(openssl_get_cert_locations()); die;in einem PHP-Skript, das mir die Informationen über die Standardeinstellungen gab, die mein lokales PHP verwendete:

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)

Wie Sie sehen können, habe ich die ini_cafile oder die ini-Option curl.cainfo gesetzt. In meinem Fall würde curl jedoch versuchen, die "default_cert_file" zu verwenden, die nicht vorhanden war.

Ich habe die Datei von https://curl.haxx.se/ca/cacert.pem an den Speicherort für "default_cert_file" (c: /openssl-1.0.1c/ssl/cert.pem) kopiert und konnte sie abrufen arbeiten.

Dies war die einzige Lösung für mich.


Ich habe ein ähnliches Problem und mein Speicherort ist so etwas wie c: /usr/local/ssl/cert.pem, aber dieser Speicherort existiert nicht Aus diesem Grund habe ich alles andere ausprobiert, nämlich das Hinzufügen eines Zertifikatspeicherorts in der INI-Datei, aber es funktioniert nicht. Es sieht so aus, als ob Ihre Lösung funktionieren sollte, da dies sinnvoll ist, aber diesen Speicherort nicht ändern und kein Zertifikat ablegen kann an einem Ort, der nicht existiert.
AbdulMueed

Sie können versuchen, die Ordner zu erstellen und das Zertifikat an Ihrem angegebenen Pfad abzulegen.
George Donev

7

Ich hatte dieses Problem eines Tages aus heiterem Himmel, als ein Guzzle (5) -Skript versuchte, über SSL eine Verbindung zu einem Host herzustellen. Sicher, ich könnte die Option VERIFY in Guzzle / Curl deaktivieren, aber das ist eindeutig nicht der richtige Weg.

Ich habe alles versucht, was hier und in ähnlichen Threads aufgeführt ist, und bin dann schließlich mit openssl zum Terminal gegangen, um die Domain zu testen, mit der ich mich verbinden wollte:

openssl s_client -connect example.com:443 

... und erhielt die ersten Zeilen mit folgenden Angaben:

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 

... während beim Ausprobieren anderer Ziele (z. B. google.com usw.) alles gut funktioniert hat

Dies veranlasste mich, Kontakt mit der Domain aufzunehmen, zu der ich versucht hatte, eine Verbindung herzustellen, und tatsächlich hatten sie ein Problem an ihrem Ende, das sich eingeschlichen hatte. Es wurde behoben und mein Skript funktionierte wieder.

Also ... wenn Sie sich die Haare ausreißen, versuchen Sie es mit openssl und prüfen Sie, ob die Antwort von dem Ort, an dem Sie eine Verbindung herstellen möchten, stimmt. Vielleicht ist das Problem doch manchmal nicht so "lokal".


6

Ich habe eine Lösung gefunden, die für mich funktioniert. Ich habe von der neuesten Version auf Version ~ 4.0 heruntergestuft und es hat funktioniert.

Fügen Sie in composer.json "guzzlehttp / guzzle" hinzu: "~ 4.0"

Hoffe es hilft jemandem


Dadurch wird auch verhindert, dass Sie Funktionen der Version 5/6 verwenden. Setzen Sie stattdessen in einem Parameter-Array (3. Parameter der Anforderungsmethode) "verify" auf "false": $ client-> request ('GET', '/', ['verify' => false]);
S ..

3

Stellen Sie sicher, dass Sie die php.iniDatei direkt in Ihrem Fenster-Explorer öffnen . (in meinem Fall :) C:\DevPrograms\wamp64\bin\php\php5.6.25.

Verwenden Sie nicht die Verknüpfung zu php.iniim Menü des Wamp / Xamp-Symbols in der Taskleiste. Diese Verknüpfung funktioniert in diesem Fall nicht.

Dann bearbeiten Sie das php.ini:

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

und

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

Nach dem Speichern müssen php.iniSie im Wamp-Symbol nicht "Alle Dienste neu starten" oder CMD schließen / erneut öffnen.


2

Hast du es versucht..

curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);

Wenn Sie eine vertrauenswürdige Quelle verwenden, müssen Sie das SSL-Zertifikat möglicherweise nicht überprüfen.


2

Ich habe zu viel Zeit damit verbracht, dieses Problem für mich herauszufinden.

Ich hatte PHP Version 5.5 und musste auf 5.6 aktualisieren.

In Versionen <5.6 verwendet Guzzle eine eigene Datei cacert.pem, in höheren Versionen von PHP jedoch die Datei cacert.pem des Systems.

Ich habe auch die Datei von hier https://curl.haxx.se/docs/caextract.html heruntergeladen und in php.ini eingestellt.

Antwort in der Guzzles StreamHandler.php-Datei https://github.com/guzzle/guzzle/blob/0773d442aa96baf19d7195f14ba6e9c2da11f8ed/src/Handler/StreamHandler.php#L437 gefunden

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

2

Alle Antworten sind richtig; Aber das Wichtigste ist, dass Sie die richtige php.ini-Datei finden müssen. Überprüfen Sie diesen Befehl in cmd "php --ini" ist nicht die richtige Antwort um die richtige php.ini-Datei zu finden.

wenn Sie bearbeiten

curl.cainfo ="PATH/cacert.pem"

und prüfe

var_dump(openssl_get_cert_locations()); 

dann sollte curl.cainfo einen Wert haben. Wenn nicht, dann ist das nicht die richtige php.ini-Datei.

* Ich empfehle Ihnen, * .ini in wamp / bin oder xxamp / bin oder einem beliebigen Server zu suchen und diese nacheinander zu ändern und zu überprüfen. * *


1

Ich habe gerade das gleiche Problem mit dem Laravel 4 PHP Framework erlebt, das das guzzlehttp/guzzleComposer-Paket verwendet. Aus irgendeinem Grund wurde das SSL-Zertifikat für Mailgun plötzlich nicht mehr überprüft, und ich erhielt dieselbe Meldung "Fehler 60".

Wenn Sie sich wie ich auf einem Shared Hosting ohne Zugriff befinden, php.inisind die anderen Lösungen nicht möglich. In jedem Fall hat Guzzle diesen Client, der Code initialisiert, der höchstwahrscheinlich die php.iniAuswirkungen zunichte machen würde :

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

Hier erzwingt Guzzle die Verwendung seiner eigenen internen cacert.pem-Datei, die wahrscheinlich veraltet ist, anstatt die von der cURL-Umgebung bereitgestellte zu verwenden . Durch Ändern dieser Zeile (zumindest unter Linux) wird Guzzle so konfiguriert, dass die Standard-SSL-Überprüfungslogik von cURL verwendet wird, und mein Problem wurde behoben:

        'verify'          => true

Sie können dies auch festlegen, falsewenn Sie sich nicht um die Sicherheit Ihrer SSL-Verbindung kümmern, dies ist jedoch keine gute Lösung.

Da die Dateien in vendornicht manipuliert werden sollen, wäre es eine bessere Lösung, den Guzzle-Client bei Verwendung zu konfigurieren. Dies war jedoch in Laravel 4 einfach zu schwierig.

Hoffe, das erspart jemand anderem ein paar Stunden Debugging ...


1

Dies mag ein Randfall sein , aber in meinem Fall war das Problem nicht das Client-Conf (das ich bereits curl.cainfokonfiguriert hatte php.ini), sondern der Remote-Server, der nicht richtig konfiguriert wurde:

Es wurden keine Zwischenzertifikate in der Kette gesendet . Es gab keinen Fehler beim Durchsuchen der Website mit Chrome, aber mit PHP wurde der folgende Fehler angezeigt.

cURL-Fehler 60

Nachdem die Zwischenzertifikate in die Remote-Webserver-Konfiguration aufgenommen wurden, funktionierte es.

Auf dieser Site können Sie die SSL-Konfiguration Ihres Servers überprüfen:

https://whatsmychaincert.com/


1

Wenn ich laufe, 'var_dump(php_ini_loaded_file());' bekomme ich diese Ausgabe auf meiner Seite 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' (length=50)'

und damit PHP meine Zertifizierungsdatei lädt, musste ich die Datei php.ini in diesem Pfad bearbeiten 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' und hinzufügen, openssl.cafile="C:/Development/bin/php/php7.2.4/extras/ssl/cacert.pem"wo ich meine Zertifizierungsdatei heruntergeladen hatte, und sie unter https://curl.haxx.se/docs/caextract.html ablegen

bin auf Windows 10, mit Drupal 8, Wamp und PHP7.2.4


0

Ich habe eine ordnungsgemäße Lösung für dieses Problem. Lassen Sie uns versuchen, die Hauptursache für dieses Problem zu verstehen. Dieses Problem tritt auf, wenn die SSL von Remoteservern nicht mithilfe von Stammzertifikaten im Zertifikatspeicher Ihres Systems überprüft werden kann oder die SSL von Remoteservern nicht zusammen mit Kettenzertifikaten installiert ist. Wenn Sie ein Linux-System mit Root-SSH-Zugriff haben, können Sie in diesem Fall versuchen, Ihren Zertifikatspeicher mit dem folgenden Befehl zu aktualisieren:

update-ca-certificates

Wenn dies immer noch nicht funktioniert, müssen Sie das Stamm- und Zwischenzertifikat des Remote-Servers in Ihrem Zertifikatspeicher hinzufügen. Sie können Root- und Zwischenzertifikate herunterladen und im Verzeichnis / usr / local / share / ca-certificates hinzufügen und dann den Befehl ausführen update-ca-certificates. Dies sollte den Trick tun. Ebenso können Sie für Windows suchen, wie Sie Stamm- und Zwischenzertifikate hinzufügen.

Die andere Möglichkeit, dieses Problem zu lösen, besteht darin, das Remoteserver-Team zu bitten, das SSL-Zertifikat als Bündel aus Domänenstammzertifikat, Zwischenzertifikat und Stammzertifikat hinzuzufügen.


-1

Wenn Sie Windows verwenden, ist Ihr Pfadtrennzeichen "\" (und "/" unter Linux). Versuchen Sie es mit der Konstante DIRECTORY_SEPARATOR. Ihr Code wird portabler.

Versuchen:

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

BEARBEITEN: und schreiben Sie den vollständigen Pfad. Ich hatte einige Probleme mit relativen Pfaden (vielleicht wird Curl von einem anderen Basisverzeichnis ausgeführt?)


1
Dies würde keinen Unterschied machen, da die tatsächlichen cURL-Einstellungen außerhalb Ihrer Kontrolle liegen, wenn Sie diese bestimmte Stripe-Bibliothek verwenden.
Ja͢ck

-1

Wenn Sie WAMP verwenden, sollten Sie auch die Zertifikatzeile in der php.ini für Apache hinzufügen (neben der Standarddatei php.ini):

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

funktioniert für php5.3 +


Ja! Achten Sie darauf, sowohl die Apache- als auch die PHP-Version der php.ini-Dateien zu bearbeiten. Für WAMP-Benutzer war diese Antwort die einzige, die mein Problem löste
MavBzh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.