PHP - Error de certificado SSL: no se puede obtener el certificado de emisor local

189

Estoy ejecutando PHP Versión 5.6.3 como parte de XAMPP en Windows 7.

Cuando intento usar la API de Mandrill, aparece el siguiente error:

Excepción no detectada 'Mandrill_HttpError' con el mensaje 'Error en la llamada API a los mensajes / plantilla de envío: problema con el certificado SSL: no se puede obtener el certificado del emisor local'

Ya probé todo lo que leí en StackOverflow, incluida la adición de lo siguiente al archivo php.ini:

curl.cainfo = "C:\xampp\php\cacert.pem"

Y, por supuesto, descargó en esa ubicación el archivo cacert.pem de http://curl.haxx.se/docs/caextract.html

pero después de todo eso, reinició XAMPP y el servidor Apache pero aún obtenía el mismo error

Realmente no sé qué más probar.

¿Alguien puede aconsejar sobre qué más puedo probar?

Dor Dadush
fuente
Vea mi respuesta: stackoverflow.com/a/29649024/660410
Michal-sk
3
También asegúrese de haber descomentado esa línea eliminando el inicio ';'. debería ser curl.cainfo = "C: \ xampp \ php \ cacert.pem" en lugar de; curl.cainfo = "C: \ xampp \ php \ cacert.pem"
Jon Tan
¿Usar HTTPS sobre HTTP también causaría este error?
javiniar.leonard

Respuestas:

366

¡Finalmente conseguí que esto funcione!

  1. Descargue el paquete de certificados .

  2. Ponlo en alguna parte. En mi caso, ese fue el c:\wamp\directorio (si está utilizando Wamp 64 bit, entonces es c:\wamp64\).

  3. Habilite mod_sslen Apache y php_openssl.dllen php.ini(descomente quitándolos ;al principio). Pero tenga cuidado, mi problema fue que tenía dos php.iniarchivos y necesito hacer esto en los dos. Uno es el que obtiene del icono de la barra de tareas de WAMP, y otro es, en mi caso, enC:\wamp\bin\php\php5.5.12\

  4. Agregue estas líneas a su certificado en ambos php.iniarchivos:

    curl.cainfo="C:/wamp/cacert.pem"
    openssl.cafile="C:/wamp/cacert.pem"
    
  5. Reinicie los servicios de Wamp.

Mladen Janjetovic
fuente
3
En mi caso, ese era el directorio c: \ xamp \ y su Windows 7 y esta solución funciona perfectamente ... muchas gracias ...
Manu RS
1
El paquete de certificados más reciente se puede descargar del sitio curl original curl.haxx.se/docs/caextract.html
Paul
1
En mi caso, la línea tenía un ;comienzo y me llevó horas darme cuenta de que significa que es un comentario. por lo que para noobs como yo, hay que quitar el ;así
abhyudayasrinet
1
@SurajNeupane no estoy seguro, pasé mucho tiempo para obtener este en ese entonces, uso máquinas virtuales, como Homestead y no tengo que lidiar con esto. Este fue un caso específico
Mladen Janjetovic el
2
Esta es la claveBut be careful, my problem was that I had two php.ini files and I need to do this in both of them. One is the one you get from your WAMP taskbar icon, and another one is, in my case, in C:\wamp\bin\php\php5.5.12\
AA
127

Descargo de responsabilidad: este código hace que su servidor sea inseguro.

Tuve el mismo problema en el archivo Mandrill.php después de la línea número 65 donde dice $ this-> ch = curl_init ();

Agregue las siguientes dos líneas:

curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);

Esto resolvió mi problema y también envió un correo electrónico usando localhost, pero sugiero NO usarlo en la versión en vivo en vivo. En su servidor en vivo, el código debería funcionar sin este código.

Shehzad Nizamani
fuente
1
¿Hay alguna cosa que pueda intentar para que mi entorno de desarrolladores funcione sin esta omisión?
Dor Dadush
44
para mí, con solo ponerme CURLOPT_SSL_VERIFYPEERa falsetrabajar.
Francisco Corrales Morales
29
Si bien es técnicamente correcto, deshabilitar SSL es una mala idea. Incluso en localhost, es mejor cargar correctamente los certificados como se menciona en la otra respuesta.
Espinal
Si bien eres técnicamente correcto, deshabilitar SSL es una mala idea. Incluso si es vehementemente resistente a trabajar de otra manera, es mejor perder su trabajo que hacer las cosas de la manera inadecuada sys-admin. @Spinal
45

Gracias @Mladen Janjetovic,

Su sugerencia funcionó para mí en mac con ampps instalado.

Copiado: http://curl.haxx.se/ca/cacert.pem

A: /Applications/AMPPS/extra/etc/openssl/certs/cacert.pem

Y actualizado php.inicon esa ruta y reinicia Apache:

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"
openssl.cafile="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"

Y aplicó la misma configuración en la instalación de Windows AMPPS y funcionó perfectamente también.

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/Ampps/php/extras/ssl/cacert.pem"
openssl.cafile="C:/Ampps/php/extras/ssl/cacert.pem"

: Lo mismo para wamp.

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"
openssl.cafile="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"

Si está buscando generar un nuevo certificado SSL usando SAN para localhost, los pasos en esta publicación funcionaron para mí Centos 7 / Vagrant / Chrome Browser.

Damodar Bashyal
fuente
18

Cuando vea la página http://curl.haxx.se/docs/caextract.html , notará en letras grandes una sección llamada:

RSA-1024 eliminado

Léalo, luego descargue la versión de los certificados que incluye los certificados 'RSA-1024'. https://github.com/bagder/ca-bundle/blob/e9175fec5d0c4d42de24ed6d84a06d504d5e5a09/ca-bundle.crt

Esos trabajarán con Mandrill.

Deshabilitar SSL es una mala idea.

Arturo Alvarado
fuente
1
Esto solucionó un problema con AWS / Guzzle / cURL con el que he estado luchando todo el día. ¡Gracias!
nulo
@voidstate Sé que esto es antiguo, pero también puede omitirlo en guzzle usando este ['verificar' => false], para ver el documento completo en ssl / curl / guzzle vaya aquí guzzle.readthedocs.org/en/latest/…
John
@John, pero eso deshabilitaría la verificación SSL, que no es lo que quieres hacer, así que no te sugiero que hagas eso.
Arturo Alvarado
1
Para Windows, deberá guardar los archivos en su servidor (por ejemplo, en C: \ curl \ curl-ca-bundle.crt), luego agregue lo siguiente a su php.ini: [curl] curl.cainfo = " C: /curl/curl-ca-bundle.crt "[openssl] openssl.cafile =" C: /curl/curl-ca-bundle.crt "
anulado el
Acabo de tener esto después de que funcionó perfectamente durante años (incluso sobrevivió a un cambio de servidor) pero tengo problemas para entender exactamente lo que está sucediendo aquí. ¿Se actualizó curl o openssl y se cambió el paquete ca a uno incompatible con mailchimp?
Sammaye
11

Los pasos anteriores, aunque útiles, no funcionaron para mí en Windows 8. No sé la correlación, pero los pasos a continuación funcionaron. Básicamente un cambio en el archivo cacert.pem. Espero que esto ayude a alguien.

  • Descargue el archivo cacert.pem desde aquí: http://curl.haxx.se/docs/caextract.html
  • Guarde el archivo en su carpeta de instalación de PHP. (por ejemplo: si usa xampp, guárdelo en c: \ Installation_Dir \ xampp \ php \ cacert.pem).
  • Abra su archivo php.ini y agregue estas líneas:
  • curl.cainfo = "C: \ Installation_Dir \ xampp \ php \ cacert.pem" openssl.cafile = "C: \ Installation_Dir \ xampp \ php \ cacert.pem"
  • Reinicie su servidor Apache y eso debería solucionarlo (simplemente detenga e inicie los servicios según sea necesario).
HopeKing
fuente
11

Encontré una nueva solución sin ninguna certificación requerida para llamar a curl, solo agregue un código de dos líneas.

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
Sharma Manish
fuente
9
Si bien esto puede funcionar, no se recomienda en absoluto. Básicamente está diciendo que confíe en todos los certificados ... y también abre su aplicación para posibles ataques si olvida y su código llega a producción con este cambio ... realmente no es mucho trabajo descargar el paquete CA y agregue punto PHP a él.
user919426
ese es el concepto curl, así que cada vez que use curl, agregue el código anterior
Manish sharma
8

Si no tiene acceso a php.ini , agregar este código (después de su $ch = curl_init();línea) funciona para mí:

$certificate_location = "C:\Program Files (x86)\EasyPHP-Devserver-16.1\ca-bundle.crt"; // modify this line accordingly (may need to be absolute)
curl_setopt($ch, CURLOPT_CAINFO, $certificate_location);
curl_setopt($ch, CURLOPT_CAPATH, $certificate_location);

Luego, solo tendrá que descargar ca-bundle.crt y guardarlo en la ubicación que especificó $certificate_location.

prohibición de geoingeniería
fuente
3

Tengo una solución muy simple de este problema. Puede hacerlo sin ningún archivo de certificado.

Vaya a Laravel Root Folder -> Vender -> guzzlehttp -> guzzle -> src

abierta Client.php

buscar $ default Array. que se ve así ...

$defaults = [
    'allow_redirects' => RedirectMiddleware::$defaultSettings,
    'http_errors'     => true,
    'decode_content'  => true,
    'verify'          => true,
    'cookies'         => false
];

Ahora el trabajo principal es cambiar el valor de la clave de verificación .

'verify'          => false,

Entonces, después de esto, no verificará el Certificado SSL para la Solicitud CURL ... Esta Solución me funciona. Encuentro esta solución después de muchas investigaciones ...

pankaj
fuente
2

elaborando las respuestas anteriores para la implementación del servidor.

$hostname = gethostname();
if($hostname=="mydevpc")
{
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}

debe hacer el truco para el entorno de desarrollo sin comprometer el servidor cuando se implementa.

Navidad
fuente
Ejecutar diferentes partes de su código en diferentes entornos no parece un buen concepto, hace que la depuración sea más difícil
Nico Haase
2

Intenté esto funciona

abierto

vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php

y cambia esto

 $conf[CURLOPT_SSL_VERIFYHOST] = 2;
 `enter code here`$conf[CURLOPT_SSL_VERIFYPEER] = true;

a esto

$conf[CURLOPT_SSL_VERIFYHOST] = 0;
$conf[CURLOPT_SSL_VERIFYPEER] = FALSE;
Yuan Libres
fuente
0

Tuve el mismo problema durante la creación de mi aplicación en AppVeyor.

  • Descargue https://curl.haxx.se/ca/cacert.pem enc:\php
  • Habilitar openssl echo extension=php_openssl.dll >> c:\php\php.ini
  • Localizar certificadoecho curl.cainfo=c:\php\cacert.pem >> c:\php\php.ini
Boca abajo
fuente
0

Si ninguna de las soluciones anteriores funciona, intente actualizar su instalación de XAMPP a una versión más nueva.

Estaba ejecutando XAMPP con php 5.5.11, el mismo código exacto no funcionó, actualicé a XAMPP con php 5.6.28 y las soluciones anteriores funcionaron.

Además, solo actualizar PHP no funcionó tampoco parece una combinación de configuraciones de apache y php en esa versión de XAMPP.

Espero que ayude a alguien.

ccrez
fuente
0

Recibí el error como:

failed loading cafile stream: `C:\xamppPhp\apache\bin\curl-ca-bundle.crt`

Estoy usando la máquina de Windows. Entonces seguí los pasos a continuación.

1. I have downloaded .pem file from " https://curl.haxx.se/docs/caextract.html "

2. Then I kept the downloaded file inside  "C:/xamppPhp/apache/bin/" folder and renamed the same downloaded file to "curl-ca-bundle.crt".

3. I restarted XAMPP and cleared the cache.
4. It's done.

Espero que pueda ayudar a alguien

S Debasish Nayak
fuente
0

Estaba enfrentando un problema como este en mi sistema local pero no en el servidor en vivo. También mencioné otra solución en esta página antes, pero que no funcionaba en localhost. Así que encuentre una nueva solución de esto, que funcione en el servidor localhost-WAMP .

Error # cURL: problema con el certificado SSL: no se puede obtener el certificado del emisor local

a veces el sistema no pudo encontrar su cacert.pem en su disco. para que pueda definir esto en su código donde va a usar CURL

Tenga en cuenta que estoy cumpliendo todas las condiciones para esto, como la biblioteca OPEN-SSL activa y otras cosas.

revisa este código de CURL .

 $curl = curl_init();
 curl_setopt_array($curl, array(
            CURLOPT_URL =>$url,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_RETURNTRANSFER=> true,
        ));
curl_setopt($curl, CURLOPT_CAINFO, "f:/wamp/bin/cacert.pem"); // <------ 
curl_setopt($curl, CURLOPT_CAPATH, "f:/wamp/bin/cacert.pem"); // <------
$response = json_decode(curl_exec($curl),true);
$err = curl_error($curl);
curl_close($curl);

pero esta solución puede no funcionar en el servidor en vivo. debido a la ruta absoluta de cacert.pem

pankaj kumar
fuente
0

Tengo una solución adecuada para este problema, intentemos comprender la causa raíz de este problema. Este problema se produce cuando los servidores remotos SSL no se pueden verificar utilizando certificados raíz en el almacén de certificados de su sistema o no se instala SSL remoto junto con los certificados de cadena. Si tiene un sistema Linux con acceso ssh raíz, en este caso puede intentar actualizar su almacén de certificados con el siguiente comando:

update-ca-certificates

Si aún así, no funciona, entonces debe agregar el certificado raíz e intermedio del servidor remoto en su tienda de certificados. Puede descargar certificados raíz e intermedios y agregarlos en el directorio / usr / local / share / ca-certificados y luego ejecutar el comando update-ca-certificates. Esto debería funcionar. Del mismo modo, para Windows puede buscar cómo agregar certificados raíz e intermedios.

La otra forma de resolver este problema es pedirle al equipo del servidor remoto que agregue el certificado SSL como un paquete de certificado raíz de dominio, certificado intermedio y certificado raíz.

prasoon
fuente
-4

para guzzle puedes probar esto:

$client = new Client(env('API_HOST'));
$client->setSslVerification(false);

probado en guzzle / guzzle 3. *

fico7489
fuente
1
¿Hay algún punto en responder una pregunta de 3 años que tenga una respuesta aceptada con más de 200 votos a favor?
treyBake
mi respuesta es más simple que las anteriores, verá que recibiré 10 votos a favor durante unos meses ...
fico7489
1
Lo dudo mucho, no veo ninguna mención de guzzle en OP ... así que es una respuesta no relacionada. Es lo mismo cuando alguien proporciona una solución jQuery para un problema de JavaScript. Es irrelevante
treyBake
eso no cambia el hecho de que no se usa aquí. ¿Sugeriría una solución de Linux a un usuario de Windows porque es el sistema operativo del servidor más utilizado? No todos quieren usar Guzzle, personalmente nunca lo he usado una vez en mis años de usar PHP. Para mí, una solicitud HTTP realmente no es tan difícil de necesitar un paquete.
treyBake
1
totalmente consciente: simplemente no es necesario ... solo lea los documentos para curl y todo se explica por sí mismo. No se trata de ser más inteligente ... se trata de responder la pregunta correctamente
treyBake