Curl-Fehler 60, Problem mit dem SSL-Zertifikat: Selbstsigniertes Zertifikat in der Zertifikatkette

81

Ich versuche, eine Curl-Anfrage mit meiner korrekten APP_ID, APP_SECRET usw. an die zu senden

  https://oauth.vk.com/access_token?client_id=APP_ID&client_secret=APP_SECRET&code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a&redirect_uri=REDIRECT_URI 

Ich muss access_token daraus abrufen, aber eine FALSE erhalten und die curl_error()nächste Nachricht ansonsten ausdrucken:

60: SSL certificate problem: self signed certificate in certificate chain

Mein Code lautet:

    // create curl resource
    $ch = curl_init();

    // set url
    curl_setopt($ch, CURLOPT_URL, $url);
    //return the transfer as a string
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    // $output contains the output string
    $output = curl_exec($ch);
    if ( ! $output) {
        print curl_errno($ch) .': '. curl_error($ch);
    }

    // close curl resource to free up system resources
    curl_close($ch);

    return $output;

Wenn ich manuell zu dem obigen Link gehe, erhalte ich access_token gut. Warum funktioniert es nicht mit Locken? Hilfe bitte.

Victor Bocharsky
quelle
Vielleicht brauche ich ein Zertifikat mit .crtVerlängerung? Aber ich weiß nicht, wie ich ihn bekommen soll
Victor Bocharsky
1
Bitte vermeiden Sie die [gebrochene] akzeptierte Antwort. Verwenden Sie stattdessen die Antwort von @ erlangsec. Siehe auch Der gefährlichste Code der Welt: Überprüfen von SSL-Zertifikaten in Nicht-Browser-Software .
JWW

Antworten:

179

Antworten, die eine Deaktivierung vorschlagen, CURLOPT_SSL_VERIFYPEERsollten nicht akzeptiert werden. Die Frage ist "Warum funktioniert es nicht mit cURL" und wie von Martijn Hols richtig hervorgehoben, ist es gefährlich.

Der Fehler wird wahrscheinlich dadurch verursacht, dass kein aktuelles Paket von CA-Stammzertifikaten vorhanden ist. Dies ist normalerweise eine Textdatei mit einer Reihe von kryptografischen Signaturen, mit denen Curl das SSL-Zertifikat eines Hosts überprüft.

Sie müssen sicherstellen, dass Ihre Installation von PHP eine dieser Dateien enthält und auf dem neuesten Stand ist (andernfalls laden Sie eine hier herunter: http://curl.haxx.se/docs/caextract.html ).

Dann setzen Sie in php.ini :

curl.cainfo = <absolute_path_to> cacert.pem

Wenn Sie es zur Laufzeit einstellen, verwenden Sie:

curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");
erlangsec
quelle
1
Danke, aber ich suchte nach einem Vorschlag für die Arbeit mit externer API. Der Vorschlag, @SabujHassan vorzuschlagen, ist also Arbeit, und wie ich verstanden habe, bietet die von mir verwendete API kein SSL.
Victor Bocharsky
Hervorragende Lösung. Vielen Dank :)
Chandra Nakka
1
Funktioniert wie Magie. Dies sollte die Antwort sein, die "akzeptierte Antwort" ist einfach, aber aus Sicherheitsgründen ein schlechter Weg.
KristCont
Danke, wie gesagt funktioniert super! Dies sollte in der Tat die richtige Antwort sein.
PostMans
2
Es ist erwähnenswert, dass curl.cainfo in PHP 7.1 / 7.2 nicht in phpinfo () angezeigt wird, openssl.cafile jedoch. php.net/manual/en/curl.configuration.php
Elijah Lynn
57

Diese Problemumgehung ist gefährlich und wird nicht empfohlen :

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Es ist keine gute Idee, die SSL-Peer-Überprüfung zu deaktivieren. Andernfalls werden Ihre Anforderungen möglicherweise MITM-Angreifern ausgesetzt.

Tatsächlich benötigen Sie nur ein aktuelles CA-Stammzertifikat-Bundle. Die Installation eines aktualisierten ist so einfach wie:

  1. Herunterladen der aktuellen cacert.pemDatei von der cURL-Website und

  2. Festlegen eines Pfads in Ihrer php.ini-Datei, z. B. unter Windows:

    curl.cainfo=c:\php\cacert.pem

Das ist es!

Bleib sicher und geborgen.

zxcmehran
quelle
5
Sie können diese Option auch in Ihrem Code festlegen, wenn Sie nicht über die Rechte zum Bearbeiten globaler php.iniDateien curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");
verfügen
2
Arbeitete an der
Entwicklungsumgebung
2
Gut zum Testen auf dev env
Gaurav Rai
Dies ist ein schrecklicher Rat und die Antwort sollte gelöscht werden.
miken32
4
@ miken32 ja und dann schlage ich eine alternative sichere Lösung als Ersatz für die gefährliche Problemumgehung vor. Lesen Sie weiter bis zum Ende.
zxcmehran
3

Wenn die SSL-Zertifikate nicht ordnungsgemäß in Ihrem System installiert sind, wird möglicherweise folgende Fehlermeldung angezeigt:

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

Sie können dieses Problem wie folgt lösen:

Laden Sie eine Datei mit der aktualisierten Liste der Zertifikate von https://curl.haxx.se/ca/cacert.pem herunter

Verschieben Sie die heruntergeladene cacert.pemDatei an einen sicheren Ort in Ihrem System

Aktualisieren Sie Ihre php.iniDatei und konfigurieren Sie den Pfad zu dieser Datei:

sunil
quelle
Möglicherweise müssen Sie auch openssl.cafile="C:/dev/ssl/mywebsite.local.crt"­in der php.ini
François Breton
3

Wichtig: Dieses Problem hat mich ein paar Tage lang verrückt gemacht und ich konnte nicht herausfinden, was mit meinen Curl & OpenSL-Installationen los war. Ich fand schließlich heraus, dass mein Zwischenzertifikat (in meinem Fall GoDaddy) veraltet war. Ich kehrte zu meinem Godaddy-SSL-Admin-Panel zurück, lud das neue Zwischenzertifikat herunter und das Problem verschwand.

Ich bin sicher, dass dies das Problem für einige von Ihnen ist.

Anscheinend hatte GoDaddy sein Zwischenzertifikat aufgrund von Sicherheitsproblemen irgendwann geändert, da jetzt diese Warnung angezeigt wird:

"Bitte verwenden Sie unbedingt die neuen SHA-2-Zwischenzertifikate, die in Ihrem heruntergeladenen Bundle enthalten sind."

Ich hoffe, das hilft einigen von Ihnen, denn ich war verrückt und das Problem wurde auf ALLEN meinen Servern behoben.

Lee
quelle
Obwohl es nicht genau mit der Frage zusammenhängt, kann es im Allgemeinen eine brauchbare Information darstellen.
nop77svk
Die Fehlermeldungen, die Curl erzeugt, können manchmal kryptisch und irreführend sein, und ich bin sicher, dass einige Leute, die den Fehler "Selbstsigniertes Zertifikat" erhalten haben, ihn aufgrund der von mir genannten Eigenart erhalten haben. Ich wollte auch hinzufügen, dass ich beim Erstellen von Curl die Konfigurationszeichenfolge verwendet habe: ./configure --with-ca-bundle = / etc / ssl / certs / ca-bundle.crt und ich habe auch das Perl-Skript lib / mk verwendet -ca-bundle.pl, um eine schöne frische Datei ca-bundle.crt zu generieren. Ich habe einen Apache-Webserver verwendet, aber mein vorhandenes Zwischenzertifikat nicht durch das aktualisierte von Godaddy ersetzt.
Lee
-3

Fehler: Problem mit dem SSL-Zertifikat: Selbstsigniertes Zertifikat in der Zertifikatkette

Solution:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);    
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
Sundar
quelle