2009-04-08 12 views
21

Sto provando a scrivere uno script PHP utilizzando cURL che può autorizzare un utente attraverso una pagina che utilizza un certificato SSL, oltre a nome utente e password, e non riesco a ottenere passato lo stadio cert SSL.Errore nell'uso di PHP cURL con i certificati SSL

In questo caso, curl_setopt($handle, CURLOPT_VERIFYPEER, 0) purtroppo non è un'opzione. Il certificato è una parte necessaria dell'autenticazione, altrimenti viene visualizzato l'errore menzionato in this other similar SO post.

Ho provato un paio di riga di comando viene eseguito con l'arricciatura:

> curl --url https://website

Questo restituisce l'errore (60) SLL certificate problem. Se ho regolare il comando per includere l'opzione --cacert:

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

funziona bene; il sito Web auth viene restituito.

Tuttavia, ho provato il seguente codice PHP:

$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); 

avrei pensato che il codice è stato sostanzialmente in linea con i comandi di shell, ma invece ho salutato con il seguente messaggio di errore:

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

ho letto tutta la letteratura che posso trovare (in particolare su php.net e curl.haxx) e non riesco a trovare nulla che risolve questo problema. Eventuali suggerimenti?

MODIFICA: Ho provato chmod 777 servercert.cer senza successo. Tuttavia, nell'esecuzione dello script PHP con il codice precedente dalla riga di comando anziché il browser tramite php test.php, funziona perfettamente. Qualche spiegazione del perché non funziona nel browser?

EDIT 2: Queste dritte downvotes sulle uniche anime abbastanza coraggiose da rispondere a questa domanda stanno invecchiando. O contribuire con qualcosa di significativo o trasmetterlo, per favore.

+0

PHP ha sicuramente il permesso di leggere quel file? Prova a eseguire lo script dalla riga di comando: php my.php – Greg

+0

Strano! L'ho provato come hai detto tu, e ha funzionato perfettamente! Perché dovrebbe funzionare dalla riga di comando, ma non dal browser? – Magsol

+0

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

risposta

11

Poiché le cose funzionano tramite la riga di comando ma non tramite php utilizzando curl allora vorrei perseguire il problema di arricciatura.

Secondo questo URL, http://curl.haxx.se/docs/sslcerts.html, che era di riferimento in un SO post che detti articoli (reading SSL page with CURL (php)) ...

"Fino a 7.18.0, ricciolo impacchettato un file ca fascio gravemente obsoleto che è stato installato da In questi giorni, gli archivi di arricciatura non includono tutti i certificati allo . È necessario ottenerli altrove.Vedi sotto per esempio

Se il server remoto utilizza un certificato autofirmato, se non si installa un CA cert bundle, se il server utilizza un certificato firmato da una CA che non è i ncluded nel bundle si utilizza o se l'host remoto è un impostore impersonare il vostro sito preferito, e si desidera trasferire i file da questo server , effettuare una delle operazioni seguenti:"

Si passa poi a elencare un numero di passaggi che puoi provare

Dato che la versione 7.16.3 di curl è precedente alla 7.18.0, se non lo si è già, vorrei raccomandare di aggiornare i componenti di arricciatura e opensl e quindi di lavorare nell'elenco di cui sopra.

3

Ora che questa domanda è molto vecchia, ma forse potrebbe essere utile per alcuni utenti che cercano una risposta al momento.

Ho un problema simile a un'API con SSL, avendo problemi con CURL (non con i browser) il mio problema era che ho appena inserito il certificato ma non la catena di certificati/bundle. Poi l'ho messo e le cose hanno iniziato a funzionare. Quindi è importante per evitare problemi.

Spero che questo possa essere utile per qualcuno.

5

Dopo 6 anni di domande, ho riscontrato lo stesso problema su un host condiviso e apparentemente non c'è una risposta soddisfacente. Ho trovato una soluzione per me stesso, spero sia utile per tutti.

Si può provare questo config:

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

ho incontrato lo stesso errore con @Magsol: Error: error setting certificate verify locations: CAfile: /path/to/servercert.cer CApath: none; quindi ho aggiunto la quarta riga per impostare CAPath.

È lavoro con me. Ma nota, il file CA deve essere posto in una directory accessibile (con chmod 755 o 777) e sarà meglio se il file CA si trova nella stessa dir con il file PHP.

+0

Questo ha funzionato, ** solo se ho impostato il percorso come percorso assoluto ** ... se hai 'ca-bundle.crt' nella stessa directory del file PHP chiamante, significa che il percorso sarà in realtà' __DIR __. '/ ca-bundle.crt'' –

0

per elaborare e riassumere questo:

se si dispone di un file PHP utilizzando PHP curl e posizionare il certificato CA per i sistemi nella stessa directory, il codice qui sotto vi darà un punto di partenza

$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 se l'istruzione alla fine tira un doppia chiamata ... mia cattiva, regolare come tale –

+0

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