miércoles, abril 02, 2014

Consumir Servicio web bajo Https en Java


La ubicación de los certificados puede variar según la distribución de Linux.
Por ejemplo en CentOS está en: "/etc/pki/java/cacerts"
Y lo único que tenés que hacer es importar el certificado allí mediante keytool.

En otras distribuciones la ruta puede variar, he incluso podés encontrar un cacerts por instalación de Java.
Ejemplos:
/usr/lib/jvm/openjdk-1.7.0-.../security/lib/cacerts
/usr/java/openjdk-1.7.0-.../security/lib/cacerts

Pero creo que en general apuntan a usar uno centralizado como el /etc/pki/...

Consumir Servicio web bajo Https en Java

Permalink
 
Importar el certificado y manejo del almacén de certificado (keystore) en Java.
 
Este proceso consta de dos etapas: 
 
1)      Guardar el certificado del servidor en un keystore
2)      Consumir el web service indicándole a la aplicación dónde está el keystore con el certificado.
 
 
1)      Guardando el certificado del servidor en un keystore
 
En primera instancia, es necesario esclarecer que para poder comunicarse con un recurso bajo https es necesario tener instalado el certificado del servidor con el cual nos queremos comunicar. Este certificado contiene la clave pública con la cual se encripta la información que se envía y que solo el servidor sabe desencriptar con su clave privada (más información aquí). Por lo tanto, a la hora de consumir un servicio bajo https necesitaremos el certificado del servidor para poder establecer la comunicación.
 
Una vez que obtenemos el certificado debemos guardarlo en un keystore. Un keystore es básicamente un ?almacén de certificados? que nos permite agregar nuevos certificados o eliminarlos (entre otras cosas). Una manera de manipular/administrar estos keystores es mediante la herramienta "Keytool.exe" que trae el JDK.
 
En resumen, lo anterior se reduce a 2 pasos simples:
 
1.1)   Obtener el certificado
 
Con el IExplorer ir al servidor del cual quiero obtener su certificado (https://www.dominio.com/webservice). Luego ir a File->Properties->Certificates. Allí en 'Details' ir por 'Copy to File...' y elegir por ejemplo 'Base-64 encoded X.509'. Con esto se guarda el certificado en un archivo.
 
Image:Web service seguro/autenticación - wsdl certificado
  
 1.2)   Agregar el certificado en un keystore
 
Agregamos el certificado (ej) "certif.cer" en el keystore MiKeystore:
 
C:\>"c:\Program Files\Java\jdk1.5.0_05\bin\keytool.exe" -import -file certif.cer -keystore c:\MiKeystore -storepass MiPassword
 
Nota: En algun caso puede suceder que de el error siguiente en la invocación del webservice:
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to findvalid certification path to requested target
Es porque se recorrió toda la jerarquía pero no encontró una Autoridad Certificadora en la que se pueda confiar. Es decir, el certificado, fue firmado por una firma en la cual no se confia (es decir, no esta en el keystore). En ese caso, ver todos los certificados del sitio, y agregarlos todos al keystore, usando una alias distinto para cada caso (opcion -alias de la opcion -import)
 
2)      Indicando la ubicación del keystore en la aplicación java
 
Cumplidos los pasos anteriores solo queda indicarle a la aplicación la ubicación del keystore para que al momento de establecer la comunicación sepa de donde tomar el certificado. Para esto se deben configurar las "system properties": javax.net.ssl.trustStore y  javax.net.ssl.trustStorePassword. Algo que se hace comúnmente es agregar dichas propiedades en la instancia de la máquina virtual lo cual se puede hacer en las Interpreter Options de GX si la aplicación es win o agregando estas entradas a las java options del tomcat si la aplicación es web.
 
En caso contrario se pueden configurar por código agregando las siguientes líneas en la rutina que consume el servicio (o en cualquier otra parte de la aplicación que se ejecute antes de consumir el servicio):
 
java System.setProperty("javax.net.ssl.trustStore", "C:\\MiKeystore");
java System.setProperty("javax.net.ssl.trustStorePassword", "MiPassword");




No hay comentarios: