martes, 8 de mayo de 2012

Cómo encriptar las contraseñas en Tomcat 7

Las contraseñas de los pools de conexiones a base de datos y del KeyStore de certificados (cuando se usa SSL) se almacenan en archivos XML de configuración en texto claro, por defecto. Nosotros no tenemos mayor problema con esto, ya que de todos modos hay que asegurar la instalación para restringir el acceso al servidor, pero es normal que en ambientes corporativos, como Bancos o Casas de Seguros esto no esté permitido, les representa un hallazgo de seguridad y piden que estas contraseñas sean almacenadas en forma encriptada, con algún algoritmo simétrico, como TripleDES con SHA1.

Si bien esto no le añade mucha más seguridad necesariamente, porque siempre se necesita otra llave para encriptar, es normal que los clientes soliciten este tipo de cambios, algo que los desarrolladores de Tomcat no parecen entender, por lo que pude ver en los forums, encriptar estas contraseñas ha sido una petición frecuente, pero que es despreciada por ellos con el argumento de que no ofrece mayor seguridad, etc, etc, en una mezcla de arrogancia y falta de pragmatismo.

Nosotros proveemos a los suscriptores de nuestra tecnología (Dinámica Deluxe) y a nuestros clientes un JAR que le añade a Tomcat 7 la capacidad de manejar las contraseñas de los pools de BD y de Keystore en forma encriptada. El JAR se llama dinamica-tomcat.jar y contiene unas clases que reemplazan las que vienen por defecto en Tomcat y que se ocupan de leer esas contraseñas. No fue un trabajo fácil, aunque debería serlo, porque Tomcat en su diseño no provee vías muy directas para afectar esta parte y proveer un lector de contraseña encriptada, sobre todo en el caso del KeyStore.

En el caso de los pools de conexiones a base de datos es un poco más fácil, requiere solo de una clase que extiende a BasicDataSourceFactory, luego esta clase es configurada en el archivo context.xml correspondiente, usando el atributo "factory".

En el caso del KeyStore, hay que crear una clase una extensión de la clase org.apache.tomcat.util.net.SSLImplementation, la cual será luego utilizada para configurar el conector SSL usando el atributo sslImplementationName. Para ser justos con el diseño de Tomcat, si bien pudo ser más fácil, al menos existe la forma de hacerlo vía extensión y configuración. El problema en el caso del KeyStore es que se requieren 2 clases más para lograr el efecto, básicamente tuvimos que identificar las clases, copiarlas de los fuentes de Tomcat a otro paquete y hacerle los ajustes para leer el password encriptado, que van en un método específico.

El JAR que proveemos contiene unos comandos para generar la contraseña encriptada, y también para codificar la llave que se usa para encriptar y desencriptar. Por ejemplo para generar la contraseña encriptada teniendo ya la llave codificada, se usa este comando:

@java -classpath ./dinamica-tomcat.jar -Dsemilla=cGVwaXRv dinamica.tomcat.MakePassword basica
En este caso la contraseña basica queda transformada en: A31CInaRgDk=

Así queda la configuración de un pool de conexiones a base de datos con el uso de contraseña encriptada y codificada en Base64:


El atributo factory indica que vamos a usar nuestra clase para leer la configuración, en particular el atributo password.

Para el caso del KeyStore se modifica server.xml para configurar el conector SSL de esta manera:


El atributo sslImplementation le dice a Tomcat 7 que use nuestra clase, la cual permite leer el atributo password encriptado.

De esta manera proveemos a nuestros clientes una forma sencilla para resolver el problema de las contraseñas en texto claro, sin configuraciones rebuscadas y suficiente para pasar una auditoria de seguridad.

Saludos,
el Team Dinámica

No hay comentarios: