PHP - problema con autenticacion uso de certificado para consumir web service

   
Vista:

problema con autenticacion uso de certificado para consumir web service

Publicado por Txema (6 intervenciones) el 07/08/2014 16:21:29
Hola buenas tardes.

Estoy desarrollando un modulo usando cUrl, para consumir un web service autenticandome usando un certificado, bajo HTTPS. Es algo totalmente nuevo para mi, y no logro hacerlo funcionar, y escribo en este foro por si alguien pudiera echarme un cable..

Obtengo diferentes errores, segun las opciones de cUrl que use, como por ejemplo

SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

(cuando no especifico CURLOPT_CAINFO)

o

error setting certificate verify locations: CAfile: certdata.txt CApath: /etc/ssl/certs

(si especifico CURLOPT_CAINFO, pero me temo que no tengo acceso a /etc/ssl/certs en el servidor. )




Este es el codigo cUrl que estoy usando, donde quiza este cometiendo uno o varios errores.

$ch = curl_init();


// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSLVERSION,3);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

$header = array();
$header[] = 'Content-Type: text/xml;charset=UTF-8';
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_HEADER, 1);

$cafile='certdata.txt';
$caruta=getcwd();
$clientfile=getcwd().'/ws-prepago.pem';
$keyfile=getcwd().'/certificate.pem';


curl_setopt($ch, CURLOPT_CAINFO, $cafile)
curl_setopt($ch, CURLOPT_SSLCERT, $clientfile);
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $mipass);
curl_setopt($ch, CURLOPT_SSLKEY, $keyfile);
curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $mipass);

$respuesta=curl_exec($ch);
$strerror=curl_error($ch);
curl_close($ch);


Por otra parte el certificado original es un pfx a partir del cual con openSSL he creado mis ficheros .pem (espero que correctamente)

Con lo cual, no se si hay algo mal en el codigo, si estan mal generados los pem, o si falla algo en la configuracion del servidor o estoy haciendo algo mal con las rutas de los certificados...

Alquien tiene idea de que puede ser? Muchas gracias de antemano.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de xve

problema con autenticacion uso de certificado para consumir web service

Publicado por xve (5519 intervenciones) el 07/08/2014 20:43:24
Hola Txema, creo que la solución pasa por indicar que no revise el certificado SSL...

Prueba a poner CURLOPT_CAINFO y CURLOPT_SSL_VERIFYHOST como false
1
2
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

De esta manera, no revisara el certificado... coméntanos si te funciono, ok?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

problema con autenticacion uso de certificado para consumir web service

Publicado por Txema (6 intervenciones) el 07/08/2014 23:36:18
Hola xve... bueno, lo primero muchas gracias por atender mi hilo.

Lo segundo... no me lo puedo creer! pero me ha devuelto contestacion (con un codigo de error que esta documentado por el proveedor del web service y tengo que revisar que es), pero vamos, como minimo una paso ha dado, que obtengo respuesta .

En cualquier caso, por ahi lei que no se debian deshabilitar esas opciones y por esos las use con los valores por defecto.

Voy a terminar de probarlo bien todo y publicare si funciono todo ok.

Muchas gracias otra vez y un saludo xve.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

problema con autenticacion uso de certificado para consumir web service

Publicado por Txema (6 intervenciones) el 08/08/2014 00:32:29
Hola de nuevo xve... bueno, ya he hecho una prueba bien hecha y si, obtengo respuesta del web service, un error (error 9900 no catalogable).

Sin saber aun mas sobre ese error hasta que no hable con el proveedor del servicio, mi duda es:

- si deshabilito esas opciones que me comentaste, eso siginifica que no usa el certificado para la autenticacion?
- por que en ese caso? como me autentico, si me hace falta el certificado para eso precisamente?.

Quiza este preguntando algo sin sentido por que no manejo el tema de cerificados y es la primera vez que estoy desarrollando algo asi, pero la logica me dice, si no me equivoco, que ahora estoy consumiendo el web service pero sin autenticarme.

Puede ser?

un saludo.

++++++++

Bueno, me autocontesto yo solo creo. Acabo de hacer otra prueba para descartar posibilidades.
He remeado todas las lineas en las que se emplea el certificado y contraseña para la autenticacion, y el web service me responde:

Forbidden: Your client is not allowed to access the requested object.


Con lo cual, deduzco, que si que se esta empleando el certificado para autenticarse, que si me estoy autenticando correctamente y que este me devuelve un error por algun motivo (seguramente este enviando mal un xml que hay que enviar por POST imagino) y que ahora me queda hablar con el proveedor para ver de que se trata el error que me devuelve:

9900 no catalogable

Muchas gracias de nuevo. Cuando lo tenga solucionado publico mas, aunque creo que la duda por la que abri el hilo esta resuelta.

Gracias xve!!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de xve

problema con autenticacion uso de certificado para consumir web service

Publicado por xve (5519 intervenciones) el 08/08/2014 08:17:19
Hola Txema, exacto, si que se utiliza el certificado SSL, pero no se verifica su autenticidad en una empresa certificadora como puede ser symantec.

Como sabes, tu puedes tener tu certificado, pero este no tiene porque estar certificado por ninguna empresa.

Gracias por compartirlo!!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

problema con autenticacion uso de certificado para consumir web service

Publicado por Txema (6 intervenciones) el 08/08/2014 10:44:54
Hola xev.... Ok,ok....entiendo... todo empieza a tener logica... es de gran ayuda que alguien que conoce del tema te aclare puntos, y asi poder ir descartando causas del problema en base a algo.

Llevo 10 dias sin saber si el certificado que estoy usando es valido (el original era un pfx y por primera vez tuve que usar openSSL para convertirlo a pem, despues de pasar 1 dia para averiguar que un pfx en un Apache no sirve para nada...), si hay algo mal en el codigo, si el certificado es valido pero no lo estoy usando correctamente, si es un problema de permiso en las carpetas y no lo puede leer....sin saber donde tengo el problema, dificilmente puedo solucionarlo,.... y en unas horas con este hilo, ya por fin tengo la certeza de que mi certificado es valido (lo he generado correctamente), de que lo estoy usando correctamente, y de que el codigo funciona (el web service me contesta)

Con lo que el error actual y pudiendo descartar lo anterior, ya imagino a que se debe despues de ver los resultados de las pruebas que llevo. El web service solo se puede consumir desde una IP fija que debes proporcionar al proveedor previamente, y la IP de mi servidor, que obtengo en las pruebas de ayer no es la misma IP que les envie hace 10 dias para que me registraran.

Pensaba que contratando el servicio de IP dedicada, instantaneamente ya dispones de ella, pero me temo que no es asi.

Un saludo xev! thx :-)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

problema con autenticacion uso de certificado para consumir web service

Publicado por Txema (6 intervenciones) el 20/08/2014 21:30:24
Bueno, lo prometido es deuda.

La aplicacion esta funcionando (al fin!!!). El problema se soluciono, y el resto de errores que fui solventando una vez tuve claro este y comence a descartar posibles causas y tuve claro que mi certificado estaba ok, lo cual fue mucho... muchisimo.

Muchas gracias a vuestro foro y a xev en particular. Esta ayuda, que aunque parezca poca, cuando tienes abiertos varios frentes y no sabes cual es el motivo de los errores y desconoces la materia, con dos frases que te aclaren una duda sirve para desencadenar las soluciones una tras otra.

Thx :-)!!!!


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
COMO CONSUMIR UN WEB SERVICE AUTENTICANDOSE BAJO HTTPS MEDIANTE cUrl EMPLEANDO UN CERTIFICADO CLIENTE PFX EN APACHE Y ENVIAR UN XML MEDIANTE POST
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Jamas habia consumido un webservice. Jamas habia usado o un certificado para autenticarme. Jamas habia usado cUrl. Jamas habia usado openssl. Si ese es tu caso, quiza este hilo te sea de utilidad, por que a mi me puso al limite.

Googleando encontarars miles de paginas que hay respecto al tema, o alguna de sus partes... no tienen fin las paginas hablando de errores con el uso de un certificado, con el uso de las opciones de cUrl, con informacion para convertir cerificados... pues a partir de hoy aqui hay una mas.

En mi caso el problema fue que tenia tantas posibles causas del error y no dominaba ninguna como para ir descartando posibilidades: No sabia si habia convertirdo bien mi certificado, no sabia ni que tenia que convertrlo para empezar, si podia er problema de la version de openssl, si usaba las opciones correctas de cUrl, si necesitaba instalar mi certificado de algun modo especial, ubicarlo en alguna localizacion especial, darle permisos al archivo o carpeta donde se encontraban o si estaba enviando mal el xml...


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1- Primero de todo. habilita curl en tu php.ini (desremea la linea correspondiente)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
extension=php_curl.dll


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 - Convertir el pfx a pem para poder usar en Apache
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- Tu certificado pfx no vale para nada en un servidor Apache. Tienes que convertirlo a formato .pem. Y como lo haces? usando opensssl.

- Si no quieres perder un buen rato googleando para encontrar unos binarios ejecutables de opensssl para convertir tu certificado sin instaladores, sin sources.... puedes usar este enlace:

http://sourceforge.net/projects/gnuwin32/files/openssl/0.9.8h-1/openssl-0.9.8h-1-bin.zip/download?use_mirror=garr

(habran versiones mas nuevas? Seguramente si, pero Ni lo se ni me importa)

- Descomprime el rar, crea una carpeta en C:\openssl, copia todo el contenido, abre una ventana de command (inicio ejecutar cmd), cambia de directorio hasta tu carpeta c:\openssl (por ejemplo: cd.. cd.. cd openssl), copia tu archivo .pfx en tu carpeta openssl (para trabajar mas comodo... yo a estas alturas estaba bastante incomodo despues de un par de dias sin haber avanzado un paso)

- Suponiendo que tu archivo con el certificado se llama 'certificate.pfx' el cual contiene el certificado y la clave privada que te pediran para autenticarte deberas crear un certificado en formato .pem, y por otra parte exportar la clave privada a un fichero para usarla en la autenticacion (pues no...no vale pasarle una variable string como paramentro a la funcion...no... ni tampoco tu clave privada es la contraseña.... tampoco... es la clave privada que va dentro de tu certificado pfx y que debes de tener en un archivo)

- Mas cosas que te vendra bien saber: En el momento de la conversion te solicitara el password que te habran proporcionado para convertir el archivo .pfx a .pem (al menos ese era mi caso). Introducelo cuando te lo solicite. Por si no lo sabias (como fue mi caso) y te quieres ahorrar un buen rato de stress y 10 o 15 intentos hasta que lo adivines, cuando te solicita el password, el prompt recibe las teclas pulsadas aunque no se muestran en pantalla por seguridad (parece que no estas escribiendo nada pero las pulsaciones de las teclas se estan capturando, No es que cada vez que intentas escribir el pass tu teclado se bloquea....tampoco...no). O sea, escribes tu pass (invisible para todos los efectos) finalizas con ENTER y si introdujiste bien el password, te dara el mensaje de OK tras la conversion. Si no tenias ni idea de certificados, te acabas de ahorrar entre 2 y 6 dias de pelearte con google y openssl, segun tu pericia.

- A PARTIR DE TU CERTIFICADO PFX, CREAR TU KEY PRIVADA PARA AUTENTICARTE usando los siguientes comandos: (Hay otros comandos mas bonitos y mejores? Ni lo se ni me importa.)

openssl pkcs12 -in certificate.pfx -out certificate.pem -nodes
openssl rsa -in certificate.pem -out key.pem

- A PARTIR DE TU CERTIFICADO PFX, CREAR TU CERTIFICADO EN FORMATO .PEM usando el siguiente comando: (Hay otros comandos mas bonitos y mejores? Ni lo se ni me importa)
openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out certificate.pem



++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 - Consumir el Web service usando cUrl y certificado y enviar XML por POST
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- copia el certificate.pem y tu key.pem en el mismo directorio que ejecutas tu archivo .php con las sentencias cUrl, o personaliza luego el codigo para usar tus rutas.


Este es el codigo php usando cUrl: Personalizalo segun tus necesidades. Espero que no hayan errores de transcripcion. Lo he editado con el notepad para quitar las partes no necesarias


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php
 
$nombrefile='el nombre de tu archivo xml'; // en mi caso sin extension por necesidades de la aplicacion 
$miurl='url del web service a consumir';
 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Archivo XML que enviare por POST
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$lentotal=filesize($nombrefile.".xml");// me guardo el len del fichero que luego lo usare en el header tambien
$handle = fopen($nombrefile.".xml", "r");
$XPost = fread($handle, $lentotal);
fclose($handle);
 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Headers
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$header = array();
$header[0] = 'Content-Type: text/xml';
$header[1] = 'Content-Length: '.$lentotal;
 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// cURL: We send XML via CURL using POST with a http header of text/xml.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$ch = curl_init();
 
// set URL and other appropriate options
/Quiza no sean necesarias alguna de las opciones, pero en el momento que me funciono ya se me habian acabado las ganas de seguir investigando. Lo dejo en tu mano quitar las lineas sobrantes si las hubiera
 
curl_setopt($ch, CURLOPT_URL, $miurl);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSLVERSION,3);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
 
// IMPORTANTISIMO estas dos opciones con valor false. Usaras tu certificado, como bien me aclaro xev, aunque no se comprobara la firma de este. En muchas paginas te dicen QUE JAMAS se deben poner false por que entonces de que sirve un certificado que supuestamente usas por motivos de seguridad, que te saltes la comprobacion por parte de una autoridad certificadora de que este es un certificado firmado y bla bla bla bla... false y te funcionara la autenticacion usando tu clave y tu certificado, que es lo que deseamos, al menos en este caso. Quiza en otros como bien dicen JAMAS habra que establecerlo a false. Otro dia lo debatimos 
// Tampoco es necesario usar CURLOPT_CAINFO, ni CURLOPT_CAPATH. por que no queremos verificar la firma del certificado,ni buscar un ca-bundle.crt actualizado, ni modificar tu php.ini para indicar la ruta absoluta de este... entre 2 y 4 dias de investigacion en google para un beginner como yo
 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
 
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
 
//Enviamos el XML por POST. Sencillo
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $XPost);
 
//Header
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_HEADER, 0);// Incluir el Header en la respuesta
 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Autenticarte mediante tu certificado y la clave privada
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$mipass='tupassword'; //El pass que usaste en la conversion del certificado pfx a pem, y que te habran proporcionado
$clientfile=getcwd().'/certificate.pem'; // el archivo de certificado en formato .pem (para tu Apache). Ojo a los slash... es una ruta... y hay quien se los come y dice que no le funciona
$keyfile=getcwd().'/key.pem'; //el archivo que contiene la clave privada para autenticarte.
 
curl_setopt($ch, CURLOPT_SSLCERT, $clientfile); //Nombre del fichero que contiene un certificado con formato PEM.
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $mipass);
 
curl_setopt($ch, CURLOPT_SSLKEY, $keyfile); //Nombre del fichero que contiene la clave privada SSL.
curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $mipass);
 
 
//Ejecutamos el curl y almacenamos la respuesta y errores de cUrl en variables
$respuesta=curl_exec($ch); // Aqui obtendras la respuesta del web service 
$strerror=curl_error($ch); // Aqui obtendras informacion del error si ha habido alguno. En mi caso unos cuantos OPENSSL_ERROR
 
//Cerramos nuesta sesión
curl_close($ch);
 
?>

Eso es todo! Ni mas... ni menos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de xve

problema con autenticacion uso de certificado para consumir web service

Publicado por xve (5519 intervenciones) el 21/08/2014 09:52:29
Excelente Txema!!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

problema con autenticacion uso de certificado para consumir web service

Publicado por DReyes (2 intervenciones) el 04/02/2015 22:05:55
Buenas tardes Txema,

Tengo un problema similar al tuyo pero creo que a diferencia de ti... yo estoy más perdido que tú al inicio de tu problema, no sé si me podrías dar alguna explicación mas a detalle de cómo hacer dicho proceso.

Ya genere el cert.pem y key.pem pero la diferencia es que yo no enviare archivo por ahora... solo necesito enviar una serie de datos para solicitar una clave al web service.

Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

problema con autenticacion uso de certificado para consumir web service

Publicado por Txema (6 intervenciones) el 09/07/2015 20:10:16
Bueno, lo siento, por que creo que hago bastante tarde, pero justo ahora acabo de ver el email de notificacion de que alguien habia escrito en el hilo.... si puedo ayudar, aqui estoy, aunque no se si podre aportar algo, no soy ningun experto en ninguno de los puntos de los que hablo en el hilo, y de ahi el motivo de que pidiera colaboracion en este foro, tuve que solucionar este problema puntualmente, pero no es una parte de la programacion con la que este familiarizado ni de lejos.
Un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

problema con autenticacion uso de certificado para consumir web service

Publicado por DReyes (2 intervenciones) el 10/07/2015 15:47:18
Que tal no te preocupes ya pude resolver el problema que tenía, la autenticación por medio de certificados ya no la realice yo pues una empresa que nos proporciona servicios de firma la realiza por mí, yo solo consumo un webService de dicha empresa pero es solo por medio de autenticación de usuario y password.

Dejo el código que utilizo por si a alguien le sirve como base.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Incluimos la libreria NuSoap
include('lib/nusoap.php');
//Creamos la nueva instancia de NuSoap donde se pasa la url y el metodo del Web Service
$client = new nusoap_client('https://miurl.mx/WebService.svc?wsdl','wsdl');
//Checamos si existe algun error
$err = $client->getError();
if ($err)
{
	echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
}
 
//En mi caso mi Metodo requiere tres parametros: Usuario, Password y Parametro.
$param = array('usuario' => 'MiUsuario','password' => 'MiPassword',
			'Parametro' => 'Mi dato a pasar en el parametro');
//Llamo el metodo a usar con los parametros que paso en la anteriror linea
			$result = $client->call('MiMetodo', $param);
//Imprimo mi respuesta
			echo '<h2>Respuesta:</h2><pre>';
		var_dump($result);

Espero le sirva a alguien.
Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar