2009-04-08 4 views
21

Ich versuche, ein PHP-Skript mit cURL zu schreiben, das einen Benutzer über eine Seite autorisieren kann, die ein SSL-Zertifikat zusätzlich zu Benutzername und Kennwort verwendet, und ich kann nicht scheinen Nach der SSL-Zertifizierungsphase.Fehler bei der Verwendung von PHP cURL mit SSL-Zertifikaten

In diesem Fall ist curl_setopt($handle, CURLOPT_VERIFYPEER, 0) leider keine Option. Das Zertifikat ist ein erforderlicher Teil der Authentifizierung, sonst erhalte ich den Fehler this other similar SO post.

ich ein paar Befehlszeile versucht habe läuft mit Curl:

> curl --url https://website

Dies gibt den (60) SLL certificate problem Fehler. Wenn ich den Befehl gehören die --cacert Option einstellen:

> curl --url https://website --cacert /path/to/servercert.cer

Es funktioniert gut; Die Auth-Website wird zurückgegeben.

Allerdings habe ich den folgenden PHP-Code versucht:

$handle = curl_init(); 
$options = array( 
        CURLOPT_RETURNTRANSFER => false, 
        CURLOPT_HEADER   => true, 
        CURLOPT_FOLLOWLOCATION => false, 
        CURLOPT_SSL_VERIFYHOST => '0', 
        CURLOPT_SSL_VERIFYPEER => '1', 
        CURLOPT_CAINFO   => '/path/to/servercert.cer', 
        CURLOPT_USERAGENT  => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)', 
        CURLOPT_VERBOSE  => true, 
        CURLOPT_URL   => 'https://website' 
      ); 

curl_setopt_array($handle, $options); 
curl_exec($handle); 
if (curl_errno($handle)) { 
    echo 'Error: ' . curl_error($handle); 
} 
curl_close($handle); 

ich den Code im Wesentlichen analog zu den Shell-Kommandos, war hätte gedacht, aber stattdessen bin ich mit der folgenden Fehlermeldung empfangen:

Error: error setting certificate verify locations: CAfile: /path/to/servercert.cer CApath: none

Ich habe die ganze Literatur gelesen, die ich finden kann (insbesondere auf php.net und curl.haxx) und kann nichts finden, das dieses Problem behebt. Irgendwelche Vorschläge?

EDIT: Ich habe chmod 777 servercert.cer ohne Erfolg versucht. Bei der Ausführung des PHP-Skripts mit dem obigen Code von der Befehlszeile anstelle des Browsers über php test.php funktioniert es jedoch einwandfrei. Irgendeine Erklärung warum es nicht im Browser funktioniert?

EDIT 2: Diese Drive-by-Downvotes über die einzigen Seelen, die mutig genug sind, diese Frage zu beantworten, werden alt. Tragen Sie bitte etwas Sinnvolles bei oder geben Sie bitte weiter.

+0

Hat PHP definitiv die Erlaubnis, diese Datei zu lesen? Versuchen Sie, das Skript über die Befehlszeile auszuführen: php my.php – Greg

+0

Seltsam! Ich habe es getestet, wie du gesagt hast, und es hat perfekt funktioniert! Warum sollte es von der Befehlszeile aus funktionieren, nicht aber vom Browser? – Magsol

+0

http://serverfault.com/questions/121768/curl-or-ssl-problems-how-to-solve/297484#297484 –

Antwort

11

Da die Dinge funktionieren über die Befehlszeile, aber nicht über PHP mit curl dann würde ich Curl verfolgen das Problem sein.

Nach dieser URL, http://curl.haxx.se/docs/sslcerts.html, die Referenz in einem SO war Beitrag, den Sie oben zitierten (reading SSL page with CURL (php)) ...

„Bis 7.18.0, gebündelt curl eine stark veraltete ca Bundle-Datei, die installiert wurde Standardmäßig enthalten die CURL-Archive in diesen Tagen keine Benachrichtigungen unter . Sie müssen sie woanders abrufen, siehe unten zum Beispiel

Wenn der Remote-Server ein selbstsigniertes Zertifikat verwendet, wenn Sie nicht installieren CA Cert-Bundle, wenn der Server ein Zertifikat verwendet, das von einer CA signiert wurde, die nicht ist. I ncluded Sie im Bündel verwenden oder wenn der Remote-Host ein Betrüger ist Ihre Lieblingsseite Identitätswechsel, und Sie Dateien von diesem -Server zu übertragen, wählen Sie eine der folgenden Möglichkeiten:“

Es geht dann auf eine Reihe aufzulisten Schritte, die Sie ausprobieren können.

Da Ihre Version 7.16.3 von curl vor 7.18.0 liegt, würde ich Ihnen empfehlen, Ihre curl- und openssl-Komponenten zu aktualisieren und dann die oben genannte Liste zu bearbeiten.

3

Nun, dass diese Frage sehr alt ist, könnte aber vielleicht für einige Benutzer nützlich sein, die derzeit nach einer Antwort suchen.

Ich habe ein ähnliches Problem über eine API mit SSL, Probleme mit CURL (nicht mit den Browsern) mein Problem war, dass ich nur das Zertifikat, aber nicht die Kette/Bündel ceritifcates. Dann habe ich das gesagt und die Dinge haben angefangen zu arbeiten. Das ist wichtig, um Probleme zu vermeiden.

Hoffe, das kann für jemanden nützlich sein.

5

Nach 6 Jahren der Frage, ich treffe das gleiche Problem auf einem Shared-Host, und anscheinend gibt es keine befriedigende Antwort. Ich habe für mich eine Lösung gefunden, hoffe, dass es für alle nützlich ist.

Sie diese Konfigurations versuchen:

curl_setopt($config,CURLOPT_SSL_VERIFYHOST,0); 
curl_setopt($config,CURLOPT_SSL_VERIFYPEER,1); 
curl_setopt($config,CURLOPT_CAINFO,'ca-bundle.crt'); 
curl_setopt($config,CURLOPT_CAPATH,'ca-bundle.crt'); 

ich denselben Fehler mit @Magsol erfüllt: Error: error setting certificate verify locations: CAfile: /path/to/servercert.cer CApath: none; Also habe ich die 4. Zeile hinzugefügt, um CAPath zu setzen.

Es ist Arbeit mit mir. Beachten Sie jedoch, dass die CA-Datei in einem zugänglichen Verzeichnis (mit chmod 755 oder 777) abgelegt werden muss und es besser ist, wenn sich die CA-Datei im selben Verzeichnis befindet wie die PHP-Datei.

+0

Das funktionierte, ** nur, wenn ich den Pfad als absoluter Pfad ** ... wenn Sie 'ca-bundle.crt' im selben Verzeichnis wie die aufrufende PHP-Datei haben, bedeutet das, dass der Pfad tatsächlich'__DIR___ '/ ca-bundle.crt'' ist. –

0

zu erarbeiten und diese zusammenzufassen:

, wenn Sie eine PHP-Datei mit PHP curl haben und das CA-Zertifikat für Ihre Systeme im selben Verzeichnis platzieren, wird der folgende Code, den Ihnen gibt eine Starthilfe

$url = "https://myserver.mydomain.local/get_somedata.php"; 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 

//These next lines are for the magic "good cert confirmation" 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 
    curl_setopt($ch, CURLOPT_VERBOSE, true); 

//for local domains: 
//you need to get the pem cert file for the root ca or intermediate CA that you signed all the domain certificates with so that PHP curl can use it...sorry batteries not included 
//place the pem or crt ca certificate file in the same directory as the php file for this code to work 
    curl_setopt($ch, CURLOPT_CAINFO, __DIR__.'/cafile.pem'); 
    curl_setopt($ch, CURLOPT_CAPATH, __DIR__.'/cafile.pem'); 

//DEBUG: remove slashes on the next line to prove "SSL verify" is the cause  
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 

//Error handling and return result 
    if (curl_exec($ch) === false) 
     { 
     $result = curl_error($ch); 
     } 
    else 
     { 
     $result = curl_exec($ch); 
     } 
    // Close handle 
    curl_close($ch); 
    return $result; 
+0

oops wenn die Anweisung am Ende eine zieht Doppelanruf ... mein Fehler, stellen Sie so ein –

+0

$ data = curl_exec ($ ch); if ($ data === false) { $ ergebnis = curl_error ($ ch); } sonst { $ result = $ data; } –