Acceso de PayPal: certificado SSL: no se puede obtener el certificado de emisor local

Estoy trabajando con cUrl y PHP para hacer una solicitud a un servidor (para el acceso de PayPal)

El sitio web para desarrolladores de Paypal nunca menciona que se requiere un certificado SSL para usar la API de acceso de PayPal; sin embargo, el código que uso para solicitar el token es el siguiente:

$options = array( CURLOPT_URL => $url, CURLOPT_POST => 1, CURLOPT_VERBOSE => 1, CURLOPT_POSTFIELDS => $postvals, CURLOPT_RETURNTRANSFER => 1, CURLOPT_SSLVERSION => 3 ); curl_setopt_array($ch, $options); $response = curl_exec($ch); echo curl_error($ch); 

Este eco emite el siguiente error:

 SSL certificate problem: unable to get local issuer certificate 

Mis preguntas son:

1) ¿Necesito SSL para usar el acceso de PayPal si solo necesito obtener el correo electrónico del usuario?

2) si no necesito SSL ¿por qué ocurre este error?

PD: el punto final es el siguiente: https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/tokenservice

La solución correcta es arreglar su configuración de PHP … configurar CURLOPT_SSL_VERIFYPEER en falso es un truco rápido, pero está mal al deshabilitar la validación del certificado por su autoridad de certificación. Esto lo expone a un ataque de hombre en el medio.

Es fácil de arreglar ( php 5.3.7 o superior ) – Descargue un archivo de lista con las autoridades de certificación actualizadas y agregue esta configuración a su php.ini
curl.cainfo=cacert.pem

¡Reinicia tu servidor web, y funcionará!

Puede deshabilitar la verificación SSL (que está habilitada por defecto a partir de cURL 7.10), agregando esto:

 CURLOPT_SSL_VERIFYPEER, false 

a sus $options , sin embargo , la forma correcta es mantener la validación habilitada.

AVISO DE SEGURIDAD

Si el sitio remoto usa un certificado emitido por una CA conocida pero la validación sigue fallando, entonces el certificado más probable está incorrectamente configurado en el servidor remoto (falta de certificados intermedios, etc.). Alternativamente, su sistema no tiene idea acerca de la Autoridad de certificación utilizada que firmó el certificado del objective. En tal caso, debe utilizar curl.cainfo ( documentación ) de php.ini para apuntar a un archivo PEM válido con todas las CA admitidas, lo que haría que su configuración valide correctamente la cadena del emisor.

Tenga en cuenta que al configurar CURLOPT_SSL_VERIFYPEER en false , NO está resolviendo el problema. Usted está trabajando alrededor. Todo se trata de seguridad, así que está bien hacer eso por un tiempo, pero desplegarlo en la producción no es prudente, educadamente hablando, ya que estarás abierto a Man In The Middle Attack . Usted ha sido advertido.

tengo exactamente el mismo problema

 Can't connect to PayPal to validate IPN message: SSL certificate: unable to get local issuer certificate 

Usé los ejemplos de código generados en paypal’s github encontrados aquí (utilicé PHP): https://github.com/paypal/ipn-code-samples

Descargué ambos certs e intenté probar ambos desde curl: http://curl.haxx.se/docs/caextract.html

Después de aproximadamente 2 horas de prueba (usando el simulador ipn de paypal) y googleando, descubrí que PayPal ipn no se puede probar en localhost , así que empujé el código en vivo e intenté probarlo, pero obtuve el mismo error (incluso con permisos establecidos en 777).

Cuando configuré CURLOPT_SSL_VERIFYPEER, false , funcionó, pero esto frustraría el propósito de tener un certificado ssl.

Después de husmear en los archivos de mi servidor, encontré un archivo curl-ca-bundle.crt en mi carpeta PHP. Decidí hardcode el CURLOPT_CAINFO en mi script de ipn paypal a esa ruta. ¡Finalmente funcionó!

Noté que este archivo .crt anterior incluía algunos certificados que no estaban en el último archivo .crt del sitio web curl. Era un grupo de certificados de verisign class 1, verisign class 2, verisign class 3 and verisign class 4 .

Aquí está la lista completa de los nombres de los certificados que agregué al archivo .crt de curl:

  • Verisign Class 1 Public Primary Certification Authority
  • Autoridad de Certificación Primaria Pública Verisign Clase 1 – G2
  • Verisign Class 1 Public Primary Certification Authority – G3
  • Verisign Class 2 Public Primary Certification Authority – G2
  • Autoridad de Certificación Primaria Pública Verisign Clase 2 – G3
  • Verisign Class 3 Public Primary Certification Authority
  • Autoridad de Certificación Primaria Pública Verisign Clase 4 – G2

Esto puede tener algo que ver con lo que decía @Andomar: el certificado de verisign de paypal no está incluido en la lista predeterminada (de manera predeterminada me refiero a curl’s default) de certificados seguros.

No tuve tiempo para depurar y averiguar exactamente qué certificado es necesario, así que simplemente los incluí a todos.

Para cualquier persona que experimente este problema en el futuro, le sugiero que obtenga los últimos cert de curl y agregue uno por uno los certificados en la lista anterior hasta que desaparezca el error.

Aquí hay un enlace para algunos de esos certificados de verisign (puede que necesite google para los otros que no figuran en la lista): http://www.symantec.com/page.jsp?id=roots

Nota *: Para ver los certificados actuales de paypal, puede ejecutar este comando en la terminal:

 openssl s_client -connect paypal.com:443 -showcerts 

Si alguien tiene más información sobre este tema, por favor coméntelo ya que pasé horas para entender todo lo anterior.

Problema de certificado SSL: no se puede obtener el certificado de emisor local

Significa que cUrl no confía en Verisign, la autoridad de certificación que responde por PayPal. Como comenta Marc B, cUrl ya no se envía con confianza a ninguna autoridad de certificación.

Puede omitir la validación de la cadena de certificados con la opción:

 CURLOPT_SSL_VERIFYPEER => 0 

Para leer cómo configurar cUrl para que confíe en Verisign, lea la documentación de cUrl .