Nov 26

Abrir conexiones java contra un servidor https

Me ha tocado abrir conexiones desde código java contra  un servidor https que requiere certificado de cliente. Me he puesto a ello y he aprendido algunas cosas.

Cuando hacemos un cliente java contra un servidor https, java verifica que el certificado que presenta ese servidor es válido. Por ello, si no los tenemos, necesitamos obtener dichos certificados y meterlos en un almacén de certificados que luego le diremos a java que es el almacén de certificados en los que confiamos. Una forma de obtener el certificado es visitar la página con el navegador y pinchar el el candadito que sale junto a la URL. Ahí podemos ver los datos del certificado y guardarlo en un fichero.

Con la herramienta keytool que viene con java podemos meter esos certificados en un fichero único, de nombre genérico "KeyStore". De hecho, el fichero por defecto que crea/usa esta herramienta keytool suele ser $HOME/.keystore. La herramienta keytool nos pedirá una clave cuando cree el fichero para protegerlo y nos pedirá la misma clave cada vez que queramos ver, añadir o borrar certificados de ese fichero. El formato de este fichero se conoce como "JKS" y es propio de java.

El certificado de cliente habitualmente nos lo darán como un fichero, protegido por una clave y su formato suele ser "PKCS12", este es un formato estándar entendido por la mayoría de las aplicaciones no java. Su extensión suele ser .p12

Pues bien, en java tenemos dos opciones para indicar cual es nuestro KeyStore y cual es nuestro certificado de cliente. Una es por medio de propiedades de sistema. Podemos arrancar nuestro código java con propiedades de este estilo

java -Djavax.net.ssl.trustStore=c:/usuario/.keystore ….

y necesitamos hasta 6 de estas propiedades: fichero, clave del fichero y formato del fichero, para el KeyStore y para el certificado del cliente.

Y la otra opción es codificarlo en java directamente, usando clases como SSLContext, TrustStoreFactory, etc, etc. Algo más complejo, pero que nos dará más versatilidad si queremos abrir varias conexiones con juegos de certificados distintos.

Cómo no, todo esto con más detalle en la chuwiki.

 

Entradas relacionadas:

One Response to “Abrir conexiones java contra un servidor https”

  1. Ivan Says:

    Hace poco tiempo estuve mirando mucho sobre este tema. Mi problema es que tenía que hacer llamadas a un WerServices mediante HTTPS y usamos AXIS2 para realizar las llamadas. En principio pensabamos incluir el certificado del servidor en la JDK de nuestro servidor de aplicaciones, pero sistemas no nos dejaba. El problema entonces era que las conexiones la maneja AXIS2 y pasaba mucho de los métodos tradicionales que muy bien explicas en la wiki. Al final dimos con la solución. Básicamente se trata de modificar una opción de AXIS2. en concreto HTTPConstants.CUSTOM_PROTOCOL_HANDLER. En esta opción hay que establecer un objeto de tipo Protocol, el cual inicilizaremos con la ruta de keystore, su password y el puerto de conexión:

    Options options = cliente._getServiceClient().getOptions();

    Protocol https = new Protocol (“https”, new TrustSSLProtocolSocketFactory (“C:\\Keystore.ks”, “password”.toCharArray()), 443);

    options.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER, https);

    cliente._getServiceClient().setOptions(options);

Leave a Reply