SSO mediante LTPA en servidores IBM WebSphere (Parte 1)

/ / Arquitectura, Blog, Digital Development
ltpa-sso-websphere-1
Presentación de DARA-Documentos Medievales Aragoneses subportal creado con nubarchiva
Alfresco - Exportar un sitio completo de Alfresco 4.2.c a Alfresco 5.0.c

En numerosas ocasiones tenemos que crear sistemas de Single Sign On (SSO) para permitir que la autenticación de los usuarios sea válida en varias aplicaciones o servidores sin necesidad de que deban introducir sus credenciales en cada uno de ellos. En el más común de estos escenarios se despliega una aplicación centralizada que gestiona las autenticaciones, generando un token único en el acceso inicial cuya verificación es solicitada cada vez que el usuario cambia de contexto.

Además de poder aplicar la solución anterior, en los servidores IBM WebSphere Application Server, en adelante WebSphere,  disponemos de un sistema basado en un token que cualquier aplicación desplegada en servidores WebSphere es capaz de generar y validar, demonimado Lightweight Third-Party Authentication (LTPA). Este sistema es el utilizado por IBM WebSphere Portal para la autenticación de usuarios, donde el portal genera el token y lo envía al usuario como una cookie http que se valida en cada petición.

 

Token LTPA

El token LTPA normalmente se envía codificado en Base64. Por ejemplo, este es el token obtenido de un IBM WebSphere Portal:

 

NL7j+PHwWVR5LKv3vvAgfA9jdHLqGuTCqlYtobNueN9Bo9Kt+6lljN+GmLlwMDmZyFqxVfIHh3LBDVMsnpCLdpLVvTm2d9KIwPzEoaHsaHdBHy7o/SU8gS/+/ocSQBkyFPo099tdIY3bhzAlljL5ICFICa5rQC1hWpgZf9XKxIrQlbDOmj6MXsxyuPqfF8QGAFT0rN7GYN1AQyY/ehTBfx52rU4PNWk/LhC+ZltCwaXhxoOWn1Ot6Fat4MbXbOiWKBfpWQ7li9UAydnJJaL7MwbOu4WCT9BPSwhrkxiiTdzw6K6uDUGDGmdS/DUnUtjx3odhLLGOqaaxNtV1/dFx8Mz4e2aPsYStLv5ECUzB4kSASPGpYFHWBjzNGXVJRRNQA2KKTNCU4t1FhK9wHiMJrMxnGr6ISMvp+Gb2F2q4a7VWWVLdjIAAkrIGYJOzbolAUBDMZ3Y8I2H+6r2nhTQIHO+Z58qMjDA8joc6jXv3QOcurw466drolbo/r9UtayN2aftpM4KNIeBkvSfR4VXQXHCP304zvIut6Pxkl3cJbx9R8cwqzWaY14Fasl0d5zT5pVgSFfXKJugCotWk66bvtJS6WxjYXdxnL0TZNDPG4mxbaMigySkb0t4tNRL5ECffoWfsgb5HQJsbtW53WepSYcaouBXwfqY65twNdE6Ptx4=

 

Se aprecia inmediatamente que es una cadena en Base64. Concretamente se trata del Base64 del resultado de cifrar la información del usuario con un algoritmo 3DES y las claves configuradas en el servidor (más adelante hablaremos de este punto). Una vez descrifrado el token obtenemos:

 

expire:1424946660000$host:ibmportal8$java.naming.provider.url:corbaloc\:iiop\:ibmportal8\:10035/WsnAdminNameService$port:10025$process.serverName:ibmportal8Cell\:ibmportal8Node\:WebSphere_Portal$security.authMechOID:oid\:1.3.18.0.2.30.2$type:SOAP$u:user\:defaultWIMFileBasedRealm/uid=admin,o=defaultWIMFileBasedRealm%1424946660000%be99CugDkbtr0rid2T7hnjALwlVssLP82d4Bpiljm1fNmndrnqIFEUl6mR0mcMky913y9g1MtJ0z7aYcSG8PWmOm5VDHWstmURmW65E0DGrueDnL7/uspx0tpeY3/rOArWsyrA2ZoHIJdeZEBhqLYPrB4mTHacJsI4X4nEpTkKQ=

 

Donde siempre estará la caducidad del token, el nombre distintivo del usuario y una firma digital, pudiendo además contener información extra, especialmente en versiones más modernas del token. La firma digital está generada con un resumen SHA-1 y cifrado RSA con claves de 1024 bits sobre los datos identificativos del usuario, asegurando la identidad de este.

Para poder realizar las operaciones criptográficas en diferentes servidores, IBM Webshpere provee de un mecanismo de exportación de claves que permite compartirlas de forma sencilla entre los nodos del SSO desde la consola de administración en: Security – Global Security – LTPA :

 

Gestión de claves LTPA en IBM WebSphere Application Server

Gestión de claves LTPA en IBM WebSphere Application Server

 

Descrifrando el token LTPA

Descrifrar el token nos puede ser útil para entender mejor el funcionamiento del sistema o verificar el formato de los tokens generados rápidamente de forma local, pero en el caso de aplicaciones desplegadas en Servidores de Aplicaciones Websphere disponemos de clases proporcionadas por el propio servidor que se encargarán de la generación y validación.

Para poder descrifrar un token LTPA necesitaremos el conjunto de claves compartidas de los servidores, que se puede obtener desde la consola de administración tal y como se mostraba en el punto anterior. Cuando exportamos las claves se nos pedirá una clave de exportación que se usará para cifrar las claves contenidas en el archivo. El archivo generado tiene el siguiente formato:

 

#IBM WebSphere Application Server key file
#Wed Nov 26 13:23:12 CET 2014
com.ibm.websphere.CreationDate=Wed Nov 26 13\:23\:12 CET 2014
com.ibm.websphere.ltpa.version=1.0
com.ibm.websphere.ltpa.3DESKey=kWUGT4MpO5aNn5ECokGtIAi/Lp8ziifzYENlyotoF/Y\=
com.ibm.websphere.CreationHost=ibmportal8
com.ibm.websphere.ltpa.PrivateKey=UkHAjacLl9/E7pE9ft9F/RMLwapI6SFXi+wN6vrqExBFvttiFzma7luiHWRVFbTs69hp1DhbgmSZLX8rYnz+zPK1eJPcqoKREBEjjtT2L+C3zy0NGrIeIJ9CuwjPHxb+tArs6JVdHfLhVH98TGpjot3SJu/dHKXzMqSsi91y7P2OrWHrxIBCmZCSUqxG4FUTFzFAdAqMIR4h6GrVHsMy8XtRl3rdDBj//wO46Z9ga3UtV3W6qSD70jNCfFGAbuSdcDD4M7w+ExdJbviRXP+KtmmKhWZMl9+XnqLIw3f6iyy6gc60/69FUnNVjRi/4k2LS856w8jZmNQoS6P4XZ4g+qbEnUNNqJaoGHBRLI7iKSE\=
com.ibm.websphere.ltpa.Realm=defaultWIMFileBasedRealm
com.ibm.websphere.ltpa.PublicKey=ANSAgix1rn3KgCPNsQ39z5TFVwSndpCztbmtDpMJBSSkcsN6G9o6lwuaCxmmClRFuTFqrxJsoO4IF6DCFlnsVC+gOAt9miroP0zneWdXTLmeI5PMPBzusqkaImb7HQ5Efgo5RzmwZ7B9uM0aZMGOu2Z7KHg9eb5PNNWpimKJ29TPAQAB

 

Los nombres de las propiedades son auto descriptivos, pero debemos tener en cuenta que las claves están cifradas mediante la contraseña que se nos solicitó en la exportación. Para obtener la clave de cifrado del token debemos descifrar el contenido de la propiedad “com.ibm.websphere.ltpa.3DESKey”. Podemos hacerlo con la siguiente función (obtenida del filtro de autenticación LTPA de Alfresco):

 

	private static byte[] getSecretKey(String ltpa3DESKey, String ltpaPassword)	throws Exception {
		String DES_DECRIPTING_ALGORITHM = "DESede/ECB/PKCS5Padding";

		MessageDigest md = MessageDigest.getInstance("SHA");
		md.update(ltpaPassword.getBytes());
		byte[] hash3DES = new byte[24];
		System.arraycopy(md.digest(), 0, hash3DES, 0, 20);
		Arrays.fill(hash3DES, 20, 24, (byte) 0);
		final Cipher cipher = Cipher.getInstance(DES_DECRIPTING_ALGORITHM);
		final KeySpec keySpec = new DESedeKeySpec(hash3DES);
		final Key secretKey = SecretKeyFactory.getInstance("DESede").generateSecret(keySpec);
		cipher.init(Cipher.DECRYPT_MODE, secretKey);
		byte[] secret = cipher.doFinal(Base64.decode(ltpa3DESKey.getBytes()));

		return secret;
	}

 

Una vez que tenemos la clave de cifrado del token, lo podemos descrifrar con las siguientes funciones (obtenidas del filtro de autenticación LTPA de Alfresco):

 

	private static byte[] decrypt(byte[] token, byte[] key, String algorithm)
			throws Exception {
		SecretKey sKey = null;

		if (algorithm.indexOf("AES") != -1) {
			sKey = new SecretKeySpec(key, 0, 16, "AES");
		} else {
			DESedeKeySpec kSpec = new DESedeKeySpec(key);
			SecretKeyFactory kFact = SecretKeyFactory.getInstance("DESede");
			sKey = kFact.generateSecret(kSpec);
		}
		Cipher cipher = Cipher.getInstance(algorithm);

		if (algorithm.indexOf("ECB") == -1) {
			if (algorithm.indexOf("AES") != -1) {
				IvParameterSpec ivs16 = generateIvParameterSpec(key, 16);
				cipher.init(Cipher.DECRYPT_MODE, sKey, ivs16);
			} else {
				IvParameterSpec ivs8 = generateIvParameterSpec(key, 8);
				cipher.init(Cipher.DECRYPT_MODE, sKey, ivs8);
			}
		} else {
			cipher.init(Cipher.DECRYPT_MODE, sKey);
		}
		return cipher.doFinal(token);
	}

	private static IvParameterSpec generateIvParameterSpec(byte key[], int size) {
		byte[] row = new byte[size];

		for (int i = 0; i < size; i++) {
			row[i] = key[i];
		}

		return new IvParameterSpec(row);
	}

 

siendo el parámetro algorithm uno de los siguientes:

	private static final String AES_DECRIPTING_ALGORITHM = "AES/CBC/PKCS5Padding";
	private static final String DES_DECRIPTING_ALGORITHM = "DESede/ECB/PKCS5Padding";

 

dependiendo de la versión del token.

 

Versiones del token LTPA

Existen dos versiones muy similares de tokens LTPA, diferentes en la información que contienen y el cifrado final que se realiza sobre la información:

  • LTPA:
    Es el formato utilizado en servidores Websphere anteriores a 6.1.
  • Contenido:
    • Caducidad del token.
    • Identidad del usuario. Incluidos pares clave-valor con información del mismo.
    • Firma digital de la identidad del usuario.
  • Cifrado: 3DES.
  • LTPA2:
    Es el formato utilizado en servidores IBM Websphere 6.1 y posteriores.
  • Contenido:
    • Caducidad del token.
    • Identidad del usuario. Incluidos pares clave-valor con información del mismo.
    • (Opcional) Contexto de autenticación del usuario.
    • Propiedades específicas del sistema LTPA2.
  • Cifrado: 3DES o AES

Cabe destacar que los servidores que soportan LTPA2 pueden validar tokens en ambos formatos de forma transparente usando el API facilitada por IBM en la instalación del servidor.

 

Conclusión y continuación

IBM provee de infraestructura de SSO en sus servidores WebSphere que permite asegurar el acceso a las aplicaciones desplegadas de manera sencilla. En el caso de aplicaciones de IBM WebSphere Portal la autenticación del usuario y posterior validación la realiza el propio portal, pero también podemos implementar las autenticación mediante tokens LTPA en aplicaciones desplegadas en WebSphere gracias al API que facilita IBM. En un siguiente artículo trataremos cómo utilizar dicho API para generar y validar tokens.

 

 


Referencias

Lightweight Third Party Authentication – (http://www-01.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/csec_ltpa.html?cp=SSAW57_8.5.5%2F1-8-1-32-2-2-0&lang=en)

Understanding LTPA – (ftp://public.dhe.ibm.com/software/integration/datapower/library/prod_docs/Misc/UnderstandingLTPA-v1.pdf)

Configuring LTPA and working with keys – (http://www-01.ibm.com/support/knowledgecenter/SSAW57_7.0.0/com.ibm.websphere.nd.doc/info/ae/ae/tsec_ltpa_and_keys.html?cp=SSAW57_7.0.0%2F1-3-0-0&lang=en)

Alfresco LTPA authenticator – (http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/COMMUNITYTAGS/V4.0d/root/modules/quickr/source/java/org/alfresco/repo/lotus/ws/impl/auth/LtpaAuthenticator.java)

1 Comment to “ SSO mediante LTPA en servidores IBM WebSphere (Parte 1)”