xxxxxxxxxx
private static final String AES_DECRIPTING_ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String DES_DECRIPTING_ALGORITHM = "DESede/ECB/PKCS5Padding";
private byte[] getSecretKey(String ltpa3DESKey, String ltpaPassword) throws Exception
{
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.decodeBase64(ltpa3DESKey.getBytes()));
return secret;
}
private 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 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);
}
// How to use it:
byte[] secretKey = getSecretKey(ltpa3DESKey, ltpaPassword);
byte[] ltpaTokenBytes = Base64.decodeBase64(ltpaToken.getBytes());
String token = new String(decrypt(ltpaTokenBytes, secretKey, DES_DECRIPTING_ALGORITHM));
// or
String token = new String(decrypt(ltpaTokenBytes, secretKey, AES_DECRIPTING_ALGORITHM));
Export the LTPA encryption key to a file from WebSphere using the admin console. You provide a passphrase and a filename.
Find the com.ibm.websphere.ltpa.3DESKey value in the exported file. This is the encrypted key.
Base64 decode the above key and decrypt with 3DES, using the passphrase provided. The decrypted value is the actual key for decrypting LTPA tokens.
Take the LtpaToken cookie, base64 decode it, and decrypt it with the key. The legacy LtpaToken cookie (which you can get with “interoperability mode”) is encrypted with 3DES; the newer LtpaToken2 cookie uses AES.
Convert to String and parse. The string looks like values%expiration%signature where the expiration is a standard UNIX timestamp, which you should use to ensure the token is still valid; and the values somewhere will contain the user DN (e.g., uid=user,ou=company,dc=com).