Error de curl 60, problema de certificado SSL: certificado autofirmado en la cadena de certificados

81

Intento enviar una solicitud curl con mi APP_ID, APP_SECRET, etc. correctos al

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

Necesito obtener access_token de él, pero obtengo un FALSO e imprimo el curl_error()siguiente mensaje de lo contrario:

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

Mi codigo es:

    // 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;

Cuando me muevo manualmente al enlace de arriba, obtengo access_token bien. ¿Por qué no funciona con rizos? Ayuda por favor.

Victor Bocharsky
fuente
¿Quizás necesito obtener un certificado con .crtextensión? Pero no sé cómo conseguirlo
Victor Bocharsky
1
Evite la respuesta aceptada [rota]. En su lugar, use la respuesta de @ erlangsec. Consulte también El código más peligroso del mundo: validación de certificados SSL en software que no es un navegador .
jww

Respuestas:

180

CURLOPT_SSL_VERIFYPEERNo se deben aceptar respuestas que sugieran deshabilitar . La pregunta es "¿Por qué no funciona con cURL?", Y como correctamente señaló Martijn Hols, es peligroso.

El error probablemente se deba a que no se dispone de un paquete actualizado de certificados raíz de CA. Este suele ser un archivo de texto con un montón de firmas criptográficas que curl usa para verificar el certificado SSL de un host.

Debe asegurarse de que su instalación de PHP tenga uno de estos archivos y que esté actualizado (de lo contrario, descargue uno aquí: http://curl.haxx.se/docs/caextract.html ).

Luego configúrelo en php.ini :

curl.cainfo = <absolute_path_to> cacert.pem

Si lo configura en tiempo de ejecución, use:

curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");
erlangsec
fuente
1
Gracias, pero estaba buscando una sugerencia para trabajar con API externa. Entonces, la sugerencia que propongo @SabujHassan es un trabajo y, según entendí, la API que usé no es proporcionar SSL.
Victor Bocharsky
Excelente solucion. Muchas gracias :)
Chandra Nakka
1
Funciona como magia. Esta debería ser la respuesta, la "respuesta aceptada" es fácil pero una mala forma por razones de seguridad.
KristCont
Gracias, como se dijo funciona excelente! De hecho, esta debería ser la respuesta correcta.
PostMans
2
Vale la pena señalar que curl.cainfo no aparece en phpinfo () en PHP 7.1 / 7.2, aunque openssl.cafile sí. php.net/manual/en/curl.configuration.php
Elijah Lynn
58

Esta solución alternativa es peligrosa y no se recomienda :

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

No es una buena idea desactivar la verificación de pares SSL. Hacerlo podría exponer sus solicitudes a atacantes MITM.

De hecho, solo necesita un paquete de certificado raíz de CA actualizado. Instalar uno actualizado es tan fácil como:

  1. Descargando un cacert.pemarchivo actualizado del sitio web cURL y

  2. Establecer una ruta en su archivo php.ini, por ejemplo, en Windows:

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

¡Eso es!

Mantente seguro y protegido.

zxcmehran
fuente
5
También puede configurar esta opción en su código si no tiene los derechos para editar el php.iniarchivo global : curl_setopt ($curl_ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");
zxcmehran
2
Trabajé en el entorno de desarrollo
cmedeiros
2
Bueno para probar en dev env
Gaurav Rai
Este es un consejo horrible y la respuesta debería eliminarse.
miken32
4
@ miken32 sí, y luego sugiero una solución alternativa segura como reemplazo de la peligrosa solución. Sigue leyendo hasta el final.
zxcmehran
3

Si los certificados SSL no están instalados correctamente en su sistema, puede recibir este error:

Error 60 de cURL: problema de certificado SSL: no se puede obtener el certificado del emisor local.

Puede resolver este problema de la siguiente manera:

Descargue un archivo con la lista actualizada de certificados de https://curl.haxx.se/ca/cacert.pem

Mueva el cacert.pemarchivo descargado a una ubicación segura en su sistema

Actualice su php.iniarchivo y configure la ruta a ese archivo:

Sunil
fuente
Además, es posible que tenga que configurar openssl.cafile="C:/dev/ssl/mywebsite.local.crt"­php.ini
François Breton
3

Importante: Este problema me volvió loco durante un par de días y no pude averiguar qué estaba pasando con mis instalaciones de curl y openssl. Finalmente descubrí que era mi certificado intermedio (en mi caso, GoDaddy) el que estaba desactualizado. Volví a mi panel de administración de godaddy SSL, descargué el nuevo certificado intermedio y el problema desapareció.

Estoy seguro de que este es el problema para algunos de ustedes.

Aparentemente, GoDaddy había cambiado su certificado intermedio en algún momento, debido a problemas de seguridad, ya que ahora muestran esta advertencia:

"Asegúrese de utilizar los nuevos certificados intermedios SHA-2 incluidos en su paquete descargado".

Espero que esto ayude a algunos de ustedes, porque me estaba volviendo loco y esto solucionó el problema en TODOS mis servidores.

Sotavento
fuente
Aunque no está exactamente relacionado con la pregunta, puede presentar una información viable en general.
peter.hrasko.sk
Los mensajes de error que produce curl a veces pueden ser crípticos y engañosos, y estoy seguro de que algunas personas que recibían el error de "certificado autofirmado" lo recibían debido a la peculiaridad que mencioné. También quería agregar que, al crear curl, usé la cadena de configuración: ./configure --with-ca-bundle = / etc / ssl / certs / ca-bundle.crt y también usé el script de perl lib / mk -ca-bundle.pl para generar un archivo ca-bundle.crt nuevo y agradable. Estaba usando el servidor web apache, pero no había reemplazado mi certificado intermedio existente con el actualizado de godaddy.
Lee
-3

Error: problema de certificado SSL: certificado autofirmado en la cadena de certificados

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
fuente