Errore cURL 60: certificato SSL: impossibile ottenere il certificato emittente locale


232

Uso WAMP in un ambiente di sviluppo locale e sto provando ad addebitare una carta di credito ma ricevo il messaggio di errore:

Errore cURL 60: problema certificato SSL: impossibile ottenere il certificato emittente locale

Ho cercato molto su Google e molte persone mi stanno suggerendo di scaricare questo file: cacert.pem , metterlo da qualche parte e fare riferimento a nel mio php.ini. Questa è la parte nel mio php.ini:

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

Tuttavia, anche dopo aver riavviato il mio server più volte e aver cambiato il percorso, ricevo lo stesso messaggio di errore.

Uso WAMP dai moduli Apache e ho abilitato ssl_module. E dalle estensioni PGP ho php_curl abilitato.

Sempre lo stesso messaggio di errore. Perché sta succedendo?

Ora sto seguendo questa correzione: Come riparare PHP CURL Error 60 SSL

Il che mi suggerisce di aggiungere queste righe alle mie opzioni cURL:

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

Dove posso aggiungere opzioni al mio cURL? Apparentemente non attraverso la riga di comando, poiché la mia CLI non trova il comando "curl_setopt"

MODIFICARE

Questo è il codice che sto eseguendo:

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

Supponendo che non ci siano problemi con il tuo codice, potrebbe essere il tuo firewall. Prova a disabilitare il firewall per testarlo.
Waqar ul islam,

non ti ho dato la risposta a questa domanda qui ? :)
Limon Monte,

@limonte possibile, ha dovuto cambiare progetto e probabilmente ha lo stesso problema con il nuovo progetto. Tornerà al problema guzzle e forse è la stessa soluzione. brb
LoveAndHappiness,

1
Hai provato l'ultima versione di Stripe? Vedo un messaggio di commit che ha cambiato qualcosa a che fare con certs ... github.com/stripe/stripe-php/commit/…
thelastshadow

1
@LoveAndHappiness hai la soluzione per questo problema? Sto affrontando lo stesso errore con la striscia. Per favore fatemi sapere se avete qualche soluzione.
Dev

Risposte:


515

Soluzione funzionante supponendo che tu sia su Windows usando XAMPP:

Server XAMPP

  1. Simile per altro ambiente
    • scaricare ed estrarre per cacert.pem qui (un formato / dati di file pulito)

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

  1. Mettilo qui nella seguente directory.

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

  1. Nel tuo php.ini inserisci questa riga in questa sezione ("c: \ xampp \ php \ php.ini"):
;;;;;;;;;;;;;;;;;;;;
; php.ini Options  ;
;;;;;;;;;;;;;;;;;;;;

curl.cainfo = "C:\xampp\php\extras\ssl\cacert.pem"
  1. Riavvia il tuo server web / apache

  2. Problema risolto!

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


6
Questo messaggio arriva a causa della tua versione di PHP. Se è superiore a PHP 5.5, arriva questo errore a causa della nuova funzionalità di PHP 5.6. PHP 5.6 controlla i certificati se stai usando cURL.
UWU_SANDUN,

9
Grazie per la risposta! Anche se consiglierei di usare cacert.pem dalla pagina curl ufficiale: curl.haxx.se/docs/caextract.html
dieBeiden

6
Volevo solo far notare a tutti coloro che non riescono a farlo funzionare - ho usato le barre in avanti curl.cainfo = "C:/cacert.pem"e ho anche dovuto riavviare il mio computer per farlo funzionare. Il riavvio del server Web non è stato sufficiente. Spero che questo aiuti:]
space_food_

1
e non dimenticare di commentare curl.cainfo(facepalm)
Edmund Sulzanok il

Ha funzionato come un fascino! Grazie
Jack

56

Attenzione Utenti Wamp / Wordpress / Windows. Ho avuto questo problema per ore e nemmeno la risposta corretta lo stava facendo per me, perché stavo modificando il file php.ini sbagliato perché la domanda ha avuto risposta a XAMPP e non per gli utenti WAMP, anche se la domanda era per WAMP.

ecco cosa ho fatto

Scarica il pacchetto di certificati.

Mettilo dentro C:\wamp64\bin\php\your php version\extras\ssl

Assicurarsi che il file mod_ssl.sosia all'interno diC:\wamp64\bin\apache\apache(version)\modules

Attiva mod_sslin httpd.confall'interno di directory di ApacheC:\wamp64\bin\apache\apache2.4.27\conf

Abilita php_openssl.dllin php.ini. Ricorda che il mio problema era che avevo due file php.ini e ho bisogno di farlo in entrambi. Il primo può trovarsi all'interno dell'icona della barra delle applicazioni WAMP qui.

inserisci qui la descrizione dell'immagine

e l'altro si trova in C:\wamp64\bin\php\php(Version)

trova la posizione per entrambi i php.inifile e trova la linea curl.cainfo =e assegnagli un percorso come questo

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

Ora salva i file e riavvia il server e dovresti essere a posto


È meno che devi fare sia php.ini che fare quello che intendi usare: se stai usando apache come client SAPI, allora modifica quello nella directory apache e / o modifica quello nel client dir se hai intenzione di usare php.exe come SAPI.
Fabien Haddadi,

3
"Devo farlo in entrambi" è la nota chiave. Grazie
Jaroslav Klimčík il

1
Funziona con Laravel 5.5 con "guzzlehttp / guzzle": "^ 6.3". Server Wamp 3.1.3. Php 7.1 *
Deepesh Thapa,

questo ha funzionato. Grazie
user4906240

Grazie per aver risposto per
Wamp

46

Se stai usando PHP 5.6 con Guzzle, Guzzle è passato al rilevamento automatico delle librerie PHP per i certificati piuttosto che al processo ( ref ). PHP delinea le modifiche qui .

Scopri dove PHP / Guzzle sta cercando certificati

Puoi scaricare dove PHP sta guardando usando:

 var_dump(openssl_get_cert_locations());

Ottenere un pacchetto di certificati

Per i test di OS X, puoi usare homebrew per installare openssl brew install openssle quindi utilizzare openssl.cafile=/usr/local/etc/openssl/cert.pemnelle impostazioni php.ini o Zend Server (in OpenSSL).

Un pacchetto di certificati è disponibile anche da curl / Mozilla sul sito web di curl: https://curl.haxx.se/docs/caextract.html

Dire a PHP dove sono i certificati

Una volta che hai un bundle, posizionalo dove PHP sta già cercando (che hai scoperto sopra) o aggiorna openssl.cafilein php.ini. (In generale, /etc/php.inio di /etc/php/7.0/cli/php.inio /etc/php/php.inisu Unix.)


3
SÌ. Dopo aver visto troppe persone suggerire l'approccio ovviamente errato del downgrade da più numeri di versione, questo rappresenta l'imho corretto. Avevo seguito i consigli degli altri sul caffè, ma non avevo i mezzi per testare perché non si caricava ancora. Questa funzione openssl_get_cert_locations () ha davvero fatto il lavoro nell'identificare il mio problema. Grazie!
Web e Flow

1
Grazie per averlo fornito openssl_get_cert_locations, ha reso il debug molto più semplice. Sembra che WAMP usi file ini diversi per apache php rispetto a php console. Nel mio caso, ho dovuto aggiungere openssl.cafile="c:/_/cacert.pem"php basato su console. L'ultima volta, quando l'ho usato tramite Apache, avevo bisogno curl.cainfo="c:/_/cacert.pem"di farlo funzionare.
psycho brm,

16

Guzzle, che viene utilizzato da cartalista / striscia , farà quanto segue per trovare un archivio certificato adeguato per verificare un certificato del server rispetto a:

  1. Controlla se openssl.cafileè impostato nel tuo file php.ini.
  2. Controlla se curl.cainfoè impostato nel tuo file php.ini.
  3. Verifica se /etc/pki/tls/certs/ca-bundle.crtesiste (Red Hat, CentOS, Fedora; fornito dal pacchetto ca-certificate)
  4. Controlla se /etc/ssl/certs/ca-certificates.crtesiste (Ubuntu, Debian; fornito dal pacchetto ca-certificati)
  5. Controlla se /usr/local/share/certs/ca-root-nss.crtesiste (FreeBSD; fornito dal pacchetto ca_root_nss)
  6. Controlla se /usr/local/etc/openssl/cert.pem(OS X; fornito da homebrew)
  7. Controlla se C:\windows\system32\curl-ca-bundle.crtesiste (Windows)
  8. Controlla se C:\windows\curl-ca-bundle.crtesiste (Windows)

Dovrai assicurarti che i valori per le prime due impostazioni siano correttamente definiti facendo un semplice test:

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

In alternativa, prova a scrivere il file nelle posizioni indicate da # 7 o # 8.


13

Se non riesci a modificare php.ini puoi anche puntare al file cacert.pem da codice come questo:

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

8

Quello che ho fatto è stato usare var_dump(openssl_get_cert_locations()); die;in qualsiasi script php, che mi ha dato le informazioni sui valori predefiniti che il mio php locale stava usando:

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)

Come puoi notare, ho impostato ini_cafile o l'opzione ini curl.cainfo. Ma nel mio caso, curl proverebbe a usare il "default_cert_file" che non esisteva.

Ho copiato il file da https://curl.haxx.se/ca/cacert.pem nella posizione per "default_cert_file" (c: /openssl-1.0.1c/ssl/cert.pem) e sono stato in grado di ottenerlo lavorare.

Questa è stata l'unica soluzione per me.


Ho un problema simile e la mia posizione è qualcosa come c: /usr/local/ssl/cert.pem ma questa posizione non esiste, fai quello che potrebbe essere, inoltre lo stesso progetto viene utilizzato dal mio coluge su mac machine potrebbe questo è il motivo, ho provato tutto il resto, che sta aggiungendo la posizione del certificato nel file .ini ma non funziona, sembra che la tua soluzione dovrebbe funzionare come ha senso ma non può cambiare quella posizione e non può mettere il certificato in una posizione che non esiste.
AbdulMueed,

Puoi provare a creare le cartelle e mettere il certificato nel percorso specificato?
George Donev,

7

Ho avuto questo problema apparire all'improvviso un giorno, quando uno script Guzzle (5) stava tentando di connettersi a un host su SSL. Certo, potrei disabilitare l'opzione VERIFY in Guzzle / Curl, ma chiaramente non è la strada giusta da percorrere.

Ho provato tutto ciò che è elencato qui e in thread simili, poi alla fine sono andato al terminale con openssl per testare il dominio con cui stavo cercando di connettermi:

openssl s_client -connect example.com:443 

... e ha ricevuto le prime righe che indicano:

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 

... mentre tutto ha funzionato bene quando provi altre destinazioni (ad es. google.com, ecc.)

Questo mi ha spinto a contattare il dominio a cui avevo cercato di connettermi e, in effetti, avevano un problema su THEIR END che si era insinuato. È stato risolto e la mia sceneggiatura è tornata a funzionare.

Quindi ... se ti stai strappando i capelli, dai a openssl una possibilità e vedi se c'è qualcosa in alto con la risposta dalla posizione che stai tentando di connettere. Forse il problema non è così 'locale' dopo tutto a volte.


6

Ho trovato una soluzione che ha funzionato per me. Ho eseguito il downgrade dall'ultimo guzzle alla versione ~ 4.0 e ha funzionato.

In composer.json aggiungi "guzzlehttp / guzzle": "~ 4.0"

Spero che aiuti qualcuno


Ciò impedirà inoltre di utilizzare qualsiasi funzionalità della versione 5/6. Invece basta impostare verifica su falso in un array di parametri (terzo parametro del metodo di richiesta): $ client-> request ('GET', '/', ['confirm' => false]);
S ..

3

Assicurati di aprire il php.inifile direttamente da Esplora risorse. (nel mio caso:C:\DevPrograms\wamp64\bin\php\php5.6.25 .

Non utilizzare il collegamento per php.ini nel menu dell'icona Wamp / Xamp nella barra delle applicazioni. Questa scorciatoia non funziona in questo caso.

Quindi modificalo php.ini:

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

e

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

Dopo il salvataggio php.ininon è necessario "Riavvia tutti i servizi" nell'icona Wamp o chiudi / riapri CMD.


2

Hai provato..

curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);

Se stai consumando una fonte attendibile, probabilmente non è necessario verificare il certificato SSL.


2

Ho trascorso troppo tempo per capire questo problema per me.

Avevo PHP versione 5.5 e dovevo aggiornare a 5.6.

Nelle versioni <5.6 Guzzle utilizzerà il proprio file cacert.pem, ma nelle versioni superiori di PHP utilizzerà il file cacert.pem del sistema.

Ho anche scaricato il file da qui https://curl.haxx.se/docs/caextract.html e impostato in php.ini.

Risposta trovata nel file StreamHandler.php di Guzzles 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.

2

Tutte le risposte sono corrette ; ma la cosa più importante è che devi trovare il file php.ini giusto. controlla questo comando in cmd "php --ini" non è la risposta giusta per trovare il file php.ini giusto.

se modifichi

curl.cainfo ="PATH/cacert.pem"

e controlla

var_dump(openssl_get_cert_locations()); 

quindi curl.cainfo dovrebbe avere un valore. in caso contrario, non è il file php.ini corretto;

* Ti consiglio di cercare * .ini in wamp / bin o xxamp / bin o in qualsiasi server che usi e cambiarli uno per uno e controllarlo. *


1

Ho appena riscontrato questo stesso problema con il framework php Laravel 4 che utilizza il guzzlehttp/guzzlepacchetto compositore. Per qualche motivo, il certificato SSL per mailgun ha smesso di validarsi all'improvviso e ho ricevuto lo stesso messaggio "errore 60".

Se, come me, sei su un hosting condiviso senza accesso a php.ini, le altre soluzioni non sono possibili. In ogni caso, Guzzle ha questo codice di inizializzazione client che molto probabilmente annullerebbe gli php.inieffetti:

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

Qui Guzzle impone l'utilizzo del proprio file cacert.pem interno, che probabilmente non è aggiornato, anziché utilizzare quello fornito dall'ambiente di cURL . La modifica di questa riga (almeno su Linux) configura Guzzle per utilizzare la logica di verifica SSL predefinita di cURL e risolto il mio problema:

        'verify'          => true

Puoi anche impostarlo su falsese non ti interessa la sicurezza della tua connessione SSL, ma questa non è una buona soluzione.

Dato che i file in vendornon devono essere manomessi, una soluzione migliore sarebbe quella di configurare il client Guzzle al momento dell'utilizzo, ma in Laravel 4 era troppo difficile farlo.

Spero che questo salvi qualcun altro un paio d'ore di debug ...


1

Questo potrebbe essere un caso limite, ma nel mio caso il problema non era il client conf (avevo già curl.cainfoconfigurato in php.ini), ma piuttosto il server remoto non era configurato correttamente:

Non ha inviato alcun certificato intermedio nella catena. Non si è verificato alcun errore durante la navigazione del sito tramite Chrome, ma con PHP ho ricevuto il seguente errore.

errore cURL 60

Dopo aver incluso i certificati intermedi nella configurazione del server web remoto ha funzionato.

Puoi utilizzare questo sito per verificare la configurazione SSL del tuo server:

https://whatsmychaincert.com/


1

quando corro 'var_dump(php_ini_loaded_file());' ottengo questo output sulla mia pagina 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' (length=50)'

e per ottenere php per caricare il mio file cert ho dovuto modificare php.ini in questo percorso 'C:\Development\bin\apache\apache2.4.33\bin\php.ini' e aggiungere openssl.cafile="C:/Development/bin/php/php7.2.4/extras/ssl/cacert.pem"dove avevo scaricato e posizionare il mio file cert da https://curl.haxx.se/docs/caextract.html

Sono su Windows 10, usando Drupal 8, Wamp e PHP7.2.4


0

Ho una soluzione adeguata di questo problema, cerchiamo di capire la causa principale di questo problema. Questo problema si verifica quando i server remoti ssl non possono essere verificati utilizzando i certificati radice nell'archivio certificati del sistema o se ssl remoto non è installato insieme ai certificati a catena. Se hai un sistema linux con accesso root ssh, in questo caso puoi provare ad aggiornare il tuo archivio certificati con il comando seguente:

update-ca-certificates

Se ancora, non funziona, è necessario aggiungere il certificato root e provvisorio del server remoto nel proprio archivio certificati. Puoi scaricare certificati root e intermedi e aggiungerli nella directory / usr / local / share / ca-certificati e quindi eseguire il comando update-ca-certificates. Questo dovrebbe fare il trucco. Allo stesso modo per Windows puoi cercare come aggiungere root e certificato intermedio.

L'altro modo per risolvere questo problema è chiedere al team del server remoto di aggiungere il certificato ssl come un pacchetto di certificati root di dominio, certificati intermedi e certificati root.


-1

Mentre stai usando Windows, penso che il tuo separatore di percorso sia '\' (e '/' su Linux). Prova a usare la costanteDIRECTORY_SEPARATOR . Il tuo codice sarà più portatile.

Provare:

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

EDIT: e scrivere il percorso completo. Ho avuto alcuni problemi con i percorsi relativi (forse il ricciolo viene eseguito da un'altra directory di base?)


1
Ciò non farebbe differenza, perché le impostazioni effettive di cURL sono fuori dal tuo controllo quando usi quella particolare libreria Stripe.
Ja͢ck,

-1

se usi WAMP dovresti anche aggiungere la linea di certificato in php.ini per Apache (oltre al file php.ini predefinito):

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

funziona per php5.3 +


Sì! Fai attenzione a modificare sia i file php.ini della versione apache che php. Per gli utenti WAMP, questa risposta è stato l'unico a risolvere il mio problema: stackoverflow.com/questions/28858351/...
MavBzh
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.