El API Apache SOAP v2.2

Este documento contiene los pasos implicados en la configuraci�n de Apache Tomcat y un sencillo Cliente SOAP para comunicaci�n SSL.

El objetivo de este documento es permitir a las personas con un m�nimo conocimiento de seguridad Java poder configurar una conexi�n SSL en una Aplicaci�n Apache SOAP/Tomcat.

.�Asumpciones

Se asume que hemos instalado Apache SOAP y Apache Tomcat, y que las aplicaciones de ejemplo de SOAP est�n funcionando.

.�Herramientas Necesarias para la Instalaci�n

.�Paso 1: Instalar JSSE

  • Antes de hacer nada, lee las instrucciones de instalaci�n de JSSE! (Est�n disponibles online en http://java.sun.com/products/jsse/install.html).
  • A�adimos los jars de JSSE a nuestro classpath. Esto deber�a a�adirlos al classpath de nuestro servidor Tomcat. Sino, los a�adimos al classpath del servidor Tomcat copiando los ficheros jar de JSSE al directorio /lib de Tomcat (por ejemplo C:\jakarta-tomcat-3.2.1\lib). Esto los cargar� autom�ticamente en la arrancada de Tomcat.

    Los ficheros jar de JSSE 1.0. que necesitamos en nuestro classpath son:

    • jsse.jar
    • jcert.jar
    • jnet.jar

.�Paso 2: Generar Certificados de Cliente y de Servidor

Es necesario generar un Certificado para el cliente y para el servidor. Estos certificados luego son importados en un keystore, al que se conectar�n el cliente y el servidor.

El keystore act�a como una base de datos para certificados de seguridad. Nosotros vamos a usar la utilidad keytool del JDK para hacer estas tareas (ver Sun's documentation para m�s informaci�n sobre esta herramiental).

.�Paso 2a: Generar una Clave y un Certificado para el Servidor

Lanzamos keytool desde un shell (o un prompt de l�nea de comandos) para generar nuestras claves p�blica y privada. Observa que los ficheros del Certificado y del keystore se generar�n en el directorio donde ejecutemos keytool.

Usamos keytool de esta forma:

keytool -genkey -alias tomcat-sv -dname "CN=[Common Name],OU=[Organisation
Unit], O=[Organisation Name], L=[Locality], S=[State Name], C=[Two-Letter
Country Code]" -keyalg RSA -keypass [private key password] -storepass [keystore
password] -keystore [keystore file name]

Por ejemplo, para generar un keystore (en el fichero server.keystore) para el servidor soapsvr.test.tcd.ie usando la password changeit (tanto para el keystore como para el certificado) en el grupo Computer Engineering del Trinity College de Dublin, Ireland, podr�amos teclear lo siguiente:

keytool -genkey -alias tomcat-sv -dname "CN=soapsvr.test.tcd.ie, OU=ComputerEngineering,
O=Trinity College Dublin, L=Dublin, S=Dublin, C=IE" -keyalg RSA -keypass
changeit -storepass changeit -keystore server.keystore

Observa que:

  • Se usa el algoritmo RSA para generar Certificados.
  • Se asegura de que el campo 'CN' que especificamos cuando creamos el certificado del servidor corresponde con el nombre de la m�quina en la que estamos ejecutando Tomcat, o nuestro navegador obtendr� un error de certificado (no es un problema en un servidor de prueba, pero es un gran problema en un servidor de producci�n!).

.�Paso 2b: Exportar el Certificado del Servidor

Desde la l�nea de comandos ejecutamos este comando para exportar nuestro certificado desde el keystore a un fichero externo (hacemos esto para poder importar el certificado en el keystore del cliente como un certificado verdadero).

keytool -export -alias tomcat-sv -storepass changeit -file server.cer -keystore server.keystore 

Si todo funciona, ahora deber�amos tener un fichero llamado server.cer que contiene el certificado del servidor.

.�Paso 2c: Generar una Clave y Certificado del Cliente

Este paso es muy similiar al de la generaci�n de la clave y el certificado para el servidor - usa la misma herramienta keytool pero con diferentes par�metros. Observa que el nombre del fichero keystore ha cambiado (ahora es client.keystore). Usamos keytool de esta forma:

keytool -genkey -alias tomcat-cl -dname "CN=Client,OU=TRL, O=IBM,
L=Yamato-shi, S=Kanagawa-ken, C=JP" -keyalg RSA -keypass changeit -storepass
changeit -keystore client.keystore

.�Paso 2d: Exportar el Certificado del Cliente

Este paso es muy similar al de la exportaci�n del certificado del servidor, usa la misma herramienta keytool pero con diferentes par�metros:

keytool -export -alias tomcat-cl -storepass changeit -file client.cer -keystore client.keystore 

Si todo funciona, deber�amos tener un fichero llamado client.cer que contiene nuestro certificado de cliente.

.�Paso 2e: Importar los Certificados en los Keystores

Queremos que el certificado del cliente sea a�adido al keystore del servidor, y que el certificado del servidor sea a�adido al keystore del cliente. Hacer esto significa que el cliente y el servidor creen el uno en el otro.

Importar el certificado del servidor en el keystore del cliente:

keytool -import -v -trustcacerts -alias tomcat -file server.cer
    -keystore client.keystore -keypass changeit -storepass changeit

Importar el certificado del cliente en el keystore del servidor:

keytool -import -v -trustcacerts -alias tomcat -file client.cer 
    -keystore server.keystore -keypass changeit -storepass changeit

.�Paso 3: Configurar Tomcat para Comunicaci�n SSL

.�Paso 3a: Modificar el Fichero de Configuraci�n de Tomcat

Necesitamos enmendar server.xml (localizado en el directorio conf de Apache Tomcat). A�adimos las siguientes l�neas al fichero xml:

<Connector className ="org.apache.tomcat.service.PoolTcpConnector"> 
<Parameter name="handler" value ="org.apache.tomcat.service.http.HttpConnectionHandler"/> 
<Parameter name="port" value="8443"/> 
<Parameter name="socketFactory" value="org.apache.tomcat.net.SSLSocketFactory" /> 
<Parameter name="keystore" value="c:\apache\soap-2_2\bin\server.keystore" /> 
<Parameter name="keypass" value="changeit"/> 
<Parameter name="clientAuth" value="true"/> 
</Connector> 

Observa que el valor usado para el par�metro keystore (mostrado en negrita) podr�a ser diferente en nuestra m�quina; deber�a contener el path completo y el nombre de fichero del fichero keystore del servidor (server.keystore) generado en el Paso 2a arriba. Observa tambi�n que el n�mero de puerto que elegimos para usar SSL en la configuraci�n de arriba es 8443. El puerto utilizado normalmente para HTTPS es 443, pero para pruebas usamos 8443.

.�Paso 3a: Probar nuestro Servidor HTTPS

En este punto, deber�amos reiniciar nuestro servidor Tomcat. Probablemente tardar� un poco en arrancar. Ahora podremos usar nuestro navegador web para probar si est� funcionando. Probamos la instalaci�n de SSL abriendo el navegador y tecleando la siguiente URL:

    https://servername:8443/index.html

Observa que servername deber�a ser reemplazado con el nombre del servidor en el que estamos ejecutando Tomcat. Si SSL est� funconando bien deber�amos ver la p�gina inicial por defecto de nuestra instalaci�n Tomcat. Nuestro navegador podr�a generar un aviso sobre certificados no-creibles o autoridades no reconocidas (s�lo hay que pulsar OK).

.�Paso 4: Modificar el Cliente SOAP para usar SSL

.�Paso 4a: Cliente Java SSL

Necesitamos configurar las propiedades antes de llamar a la URL en el cliente SOAP. Aqu� tenemos un ejemplo de cliente SOAP que llama a los clientes SOAP usando HTTPS sobre un servidor Tomcar:

// classes for ssl

import javax.net.ssl.SSLSocketFactory;
import java.security.Security;
...

    //
    // setup some ssl-specific stuff
    //
    
    // specify the location of where to find key material for the default TrustManager 
	// (this overrides jssecacerts and cacerts)
    System.setProperty("javax.net.ssl.trustStore","C:\\jdk1.3\\bin\\client.keystore");
    // use Sun's reference implementation of a URL handler for the "https" URL protocol type. 
    System.setProperty("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");       
    // dynamically register sun's ssl provider
    Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());      
    // note that the url is using https protocol and not http
    URL urls = new URL( "https://localhost:8443/soap/servlet/rpcrouter");
    
    //
    // prepare and then execute a SOAP method
    //
    
    // output some basic information
    System.out.println("\nUsing " + urls.getProtocol() + " to connect to " + 
	    urls.getHost() + " on port #" + urls.getPort());
    
    // prepare the service invocation as usual
    Call call = new Call(); 
    String urn = "urn:demo:checkflight";    
    call.setTargetObjectURI( urn ); 
    call.setMethodName( "getFlightInfo" );
    
    // set up any parameters as usual
    ...
    
    // Invoke the call
    Response resp;
    try
    {
      resp = call.invoke(urls, "");
    }
    catch (SOAPException e)
    {
      System.err.println("Caught SOAPException (" + e.getFaultCode() + "): " + e.getMessage());
      e.printStackTrace();
      return;
    }       

De nuevo, el path de directorio en negrita es un puntero al keystore del cliente. Esto podr�a ser diferente dependiendo de donde lo hayamos generado. Observa tambi�n que la url es https y no http. Es un error f�cil de cometer!

.�Paso 4b: Cliente Java SSL con Proxy [Opcional]

Si nuestro cliente necesita usar un servidor proxy para poder acceder al servicio SOAP, a�adimos las siguientes l�neas a nuestro c�digo:

	 // set name of proxy server that supports ssl 
    System.setProperty("https.proxyHost", "proxy");
	 
	// set port number for proxy server that supports ssl
    System.setProperty("https.proxyPort", "8080");   

Usamos lo siguiente para usar el Proxy sin SSL:

    System.setProperty("proxySet", "true"); // enable proxying
    System.setProperty("proxyHost", "proxy");       // set name of proxy server
    System.setProperty("proxyPort", "8080");    // set port number for proxy server

Si estamos usando proxy socks entonces configuramos estas propiedades (del sistema):

    System.setProperty("socksProxyHost", "hostname");       // set name of socks server  
    System.setProperty("socksProxyPort", "1080");       // set port number for socks server

.�Crear una Cadena de Certificados X.509

.�Introducci�n

Este conjunto de instrucciones cubre la creacci�n de credenciales mutuas entre dos entidades usando una cadena de certificados (mi certificado con una l�nea de certificados p�blicos adjuntos), que es m�s pr�ctico en un entorno de producci�n que una aproximaci�n de seguridad m�nima. En este caso un principal es creible si cualquiera de los certificados de la cadea es creible. Se necesitan herramientas adicionales: IBM KeyMan, que puede leer y env�ar certificados desde keystores en lo formatos JKS y PKCS12. Otos formatos (por ejemplo, IBM CMS Key Database) no funcionan bien, al menos en mi experiencia.

.�Descargar KeyMan

KeyMan puede ser descargado desde: http://www.alphaworks.ibm.com/tech/keyman.

.�Crear un nuevo Keystore y Keypair usando KeyMan

  • Desde la ventana inicial, pulsamos sobre el icono "create new" de la izquierda
    O
    desde una ventana KeyMan ya abierta, bajo el men� File, elegimos New
  • Especificamos el tipo de keystore (pkcs 7, 12 y JKS son las opciones)
  • La plantilla se crea inmediatamente
  • Bajo el men� Actions elegimos generate key
  • Seleccionamos el algoritmo y la longitud de la clave deseados, pulsamos OK
  • ESPERAMOS

.�Abrir un Fichero Keystore Existente

  • Desde la ventana inicial, pulsamos sobre el icono "open" de la izquierda
    O
    desde una ventana KeyMan ya abierta, bajo el men� File, elegimos Open
  • Seleccionamos "local resource", pulsamos next
  • Introducimos o navegamos buscando el nombre de fichero, pulsamos next
  • Si es aplicable, introducimos una passowrd para proteger el fichero

.�Generar un Certificado Auto-Firmado usando KeyMan (para un nuevo serverkeystore)

  • Nos aseguramos de que est� seleccionada la nueva pareja de claves (y s�lo la pareja de claves)
  • Bajo el men� Actions, elegimos Create Certificate
  • Elegimos Self-Signed Certificate, pulsamos next
  • Rellenamos la informaci�n principal de la solicitud, y pulsamos next
  • Seleccionamos un periodo de validez del certificado, pulsamos next

.�Solicitar un Certificado de Cliente usando keytool

-- usando keytool (despu�s de crear el "alias" keyEntry )

keytool -certreq {-alias alias} {-sigalg sigalg} {-file certreq_file}
[-keypass keypass] {-storetype storetype} {-keystore keystore} [-storepass
storepass] {-v} {-Jjavaoption}

Si dejamos fuera la parte "-file certreq_file", se imprimir� la solicitud pkcs10 en nuestra salida est�ndard, que podr�amos utilizar y copiar en el clipboard, transferirlo a un fichero o directamente en KeyMan (Ver el siguiente paso "enviar certificado"). La informaci�n principal de la solicitud ser� la que introdujimos usando el comando "-genkey" anteriormente.

.�Solicitar un Certificado de Cliente usando KeyMan (usando una pareja de claves)

  • Nos aseguramos de que est� seleccionada la nueva pareja de claves (y s�lo la pareja de claves)
  • Bajo el men� Actions, elegimos Request Certificate
  • Elegimos "Generate a PKCS#10 Request", pulsamos next
    O
    Si queremos obtener un certificado comercial para nuestro certificado, elegimos "Go online to a CA" (No conozco los pasos restantes para hacer esto)
  • Rellenamos la informaci�n principal de la solicitud, pulsamos next
  • Introducimos el nombre de fichero donde queremos grabar la solicitud,
    O
    elegimos copiar la solicitud en el clipboard del sistema, pulsamos next
  • La solicitud est� ahora almacenada en la localizaci�n que hemos especificado.

.�Enviar un certificado usando KeyMan

(aka actuando como nuestro propio CA, firmando una solicitud de certificado PKCS#10)

  • Abrimos el keystore que contiene el certificado privado de nuestro servidor.
  • Bajo el men� Actions, elegimos Create Certificate
  • Elegimos Sign a PKCS#10 request, pulsamos next
  • Introducimos o navegamos para buscar el nombre de fichero que contiene la solicitud,
    O
    Elegimos cargar la solicitud desde el clipboard del sistema (si lo almacenamos all�), pulsamos next
  • Revisar la informaci�n principal (recomendado: verificarlo offline en un escenario de producci�n)
  • Selecionamos el periodo de validez del nuevo certificado, pulsamos next
  • Introducimos un nombre de fichero [path-completo] donde almacenaremos el nuevo certificado, pulsamos next
  • NO RECOMENDADO: grabar el certificado en el clipboard (crear� una sola entrada de certificado en el lado del cliente en vez de una cadena de certificados).

.�Importar un nuevo certificado desde el CA usando Keytool

(despu�s de importar el certificado del servidor como un certificado de CA cre�ble)

keytool -import {-alias alias} {-file cert_file} [-keypass keypass]
{-storetype storetype} {-keystore keystore} [-storepass storepass] {-v}
{-Jjavaoption}

Simplemente deber�a decir "certificate was added to keystore" y finalizar sin ning�n di�logo. ["alias" es neustra keyEntry original; el certificado por defecto auto-firmado deber�a ser sobreescrito por el certificado firmado por la CA].

.�Importar nuestro nuevo certificado de la CA usando KeyMan

  • Bajo el men� File, elegimos Import
  • Seleccionamos "local resource", pulsamos next
  • Introducimos o navegamos buscando el nombre del fichero ("cert_file"), pulsamos next
  • Deber�amos obtener un di�logo emerfgente diciendo "Private Certificate Received", pulsamos OK

.�Grabar el fichero nuevo o modificado de keystore usando KeyMan

  • Bajo el men� File elegimos Save
  • Introducimos el nombre del fichero [path-completo] (dejamos el formato de fichero por defecto si es PKCS12), pulsamos OK
  • Introducimos una password si se nos pide
Nota: Si el servidor obtiene una cadena de certificados desde una entidad CA superor, el cliente podr�a importar ese certificado de una entidad superior como un certificado de un CA cre�ble (podr�a tener el certificado ya por defecto), y as� creer�a al certificado del servidor.

.�Troubleshooting

Un truco extremadamente �til para resolver problemas con SSL es usar las caracter�sticas de depuraci�n internas de SSL:

java -djavax.net.debug=help YourClassname

(esto no dar� un mensaje de ayuda para las caracter�sticas de depuraci�n de SSL)

.�Unknown Protocol Error

Problema:

Exception in thread "main" java.net.MalformedURLException:
unknown protocol: https

Soluci�n: Nos aseguramos de que la inicializaci�n del c�digo espec�fico-SSL sucede antes de crear un objeto java.net.URL.

.�Unrecognized SSL handshake

Problema:

ContextManager: IOException reading request, ignored - javax.net.ssl.SSLException:
Unrecognized SSL handshake.

Soluci�n: Lo m�s probable ser� que:

  • (a) nuestra URL sea http:// en lugar de https://
    o
  • (b) nuestros cliente y servidor est�n usando versiones diferentes de soap.jar (posiblemente 2.0/2.1).

.�Bad Certificate Error

Volver a realizar los pasos 2, 3 y 4.

.�Socket Write Error

Problema:

java.lang.reflect.InvocationTargetException: java.net.SocketException:
Connection aborted by peer: socket write error

Soluci�n: Este problema ocurre porque (por alguna raz�n) el servidor no pueden autentificar al cliente. Cambiamos la siguiente l�nea en server.xml:

<Parameter name="clientAuth" value="false"/>

.�Keytool Error

Problema:

keytool error: java.io.IOException: Keystore was tampered
with, or password was incorrect

Soluci�n: Intenta borrar el fichero keystore y volver a crearlo (puedes ver las instrucciones al principio de esta p�gina).

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP