Programación en castellano
-Tutoriales

El API Apache SOAP v2.2


Configurar Apache Tomcat y un simple Cliente SOAP para usar SSL

. Introducción

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).

 
Patrocinados
 

Copyright © 1999-2007 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad
Mantenida por: Claudio y Dani.

Hospedaje web y servidores dedicados linux por Ferca Network

red internet: jugar gratis | amor | navidad 2009 | registro de dominios | servidores dedicados
más internet: comprar | gratis | posicionamiento en buscadores | decoración libre | gifs animados