2009-04-08 81 views
21

Estoy tratando de escribir un script PHP usando cURL que puede autorizar a un usuario a través de una página que usa un certificado SSL, además de nombre de usuario y contraseña, y parece que no puedo obtener más allá de la etapa de certificación SSL.Error al utilizar PHP cURL con certificados SSL

Desafortunadamente, en este caso, curl_setopt($handle, CURLOPT_VERIFYPEER, 0) no es una opción. El certificado es una parte obligatoria de la autenticación; de lo contrario, aparece el error mencionado en this other similar SO post.

He probado unos cuantos de línea de comandos se ejecuta con CURL:

> curl --url https://website

Esto devuelve el error (60) SLL certificate problem. Si se ajusta el comando para incluir la opción --cacert:

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

Funciona muy bien; el sitio web de autenticación es devuelto

Sin embargo, he probado el siguiente código 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); 

yo habría pensado que el código era esencialmente análoga a los comandos de la shell, pero en cambio estoy recibidos con el mensaje de error siguiente:

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

He leído toda la literatura que puedo encontrar (particularmente en php.net y curl.haxx) y no puedo encontrar nada que solucione este problema. ¿Alguna sugerencia?

EDIT: He intentado chmod 777 servercert.cer sin éxito. Sin embargo, al ejecutar el script PHP con el código anterior desde la línea de comandos en lugar del navegador a través del php test.php, funciona perfectamente. ¿Alguna explicación de por qué no funciona en el navegador?

EDIT 2: Estos votos a la baja de las únicas almas lo suficientemente valientes como para responder a esta pregunta se están haciendo viejas. O contribuya con algo significativo o pase por aquí, por favor.

+0

¿Tiene PHP definitivamente permiso para leer ese archivo? Intente ejecutar el script desde la línea de comando: php my.php – Greg

+0

¡Extraño! ¡Lo probé como dijiste, y funcionó perfectamente! ¿Por qué funcionaría desde la línea de comandos, pero no desde el navegador? – Magsol

+0

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

Respuesta

11

Como las cosas funcionan a través de la línea de comandos pero no a través de php usando curl, entonces yo seguiría siendo curl el problema.

De acuerdo a esta URL, http://curl.haxx.se/docs/sslcerts.html, que era referencia en un SO que enviar antes citada (reading SSL page with CURL (php)) ...

"Hasta 7.18.0, rizo liado un archivo de paquete ca gravemente obsoleta que fue instalado por En estos días, los archivos curl no incluyen ningún certificado de ca en . Debe obtenerlos en otro lugar. Consulte a continuación, por ejemplo.

Si el servidor remoto utiliza un certificado autofirmado, si no instala un CA conjunto de certificado, si el servidor utiliza un certificado firmado por una CA que no es i nclu en el haz que utiliza o si el host remoto es un impostor hacerse pasar por su sitio favorito, y que desea transferir archivos desde este servidor , lleve a cabo uno de los siguientes:"

A continuación, pasa a enumerar una serie de pasos que puedes intentar

Dado que su versión 7.16.3 de curl es anterior a la 7.18.0, si no lo ha hecho aún, le recomendaría actualizar sus componentes curl y openssl y luego trabajar a través de la lista mencionada anteriormente.

3

Ahora que esta pregunta es muy antigua, pero tal vez podría ser útil para algunos usuarios que buscan una respuesta actualmente.

Tengo un problema similar sobre una API con SSL, tengo problemas con CURL (no con los navegadores) mi problema es que acabo de poner el certificado pero no la cadena/paquete ceritifcates. Luego puse eso y las cosas comenzaron a funcionar. Entonces eso es importante para evitar problemas.

Espero que esto puede ser útil para otras personas.

5

Después de 6 años de la pregunta, encuentro el mismo problema en un servidor compartido, y aparentemente no hay una respuesta satisfactoria. Encontré una solución, espero que sea útil para todos.

Puede probar esta configuración:

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

me encontré con el mismo error @Magsol: Error: error setting certificate verify locations: CAfile: /path/to/servercert.cer CApath: none; así que agregué la cuarta línea para configurar CAPath.

Es trabajo conmigo. Pero tenga en cuenta que el archivo CA debe colocarse en el directorio accesible (con chmod 755 o 777) y será mejor si el archivo CA está en el mismo directorio con el archivo PHP.

+0

Esto funcionó, ** Sólo si fijo la ruta como ruta absoluta ** ... si tiene 'ca-bundle.crt' en el mismo directorio que el archivo PHP que realiza la llamada, significa que la ruta será' __DIR __. '/ ca-bundle.crt'' –

0

Elaborar y resumir esto:

si tiene un archivo PHP usando rizo PHP y colocar el certificado de CA para sus sistemas en el mismo directorio, el código de abajo le dará el puntapié inicial

$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 si la instrucción al final tira de un doble llamada ... mi mala, ajustar como tal –

+0

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

Cuestiones relacionadas