Hey guys, I have a question about the aesEncrypt method in
org.apache.deltaspike.core.impl.crypto.DefaultCipherService.aesEncrypt.
In this method, it uses a customized key derivation function:
private SecretKeySpec getSecretKeySpec(String password)
{
byte[] pwdHash = secureHash(password);
byte[] key = Arrays.copyOf(pwdHash, 16); // use only first 128 bit
// Note: using 128 bit AES avoids requirement for "Unlimited Crypto”
patch
return new SecretKeySpec(key, "AES");
}
This function hashes the provided password once as the encryption key without
using Java’s pbkdf.
protected byte[] secureHash(String value)
{
try
{
MessageDigest md = MessageDigest.getInstance(HASH_ALGORITHM);
return md.digest(value.getBytes(UTF_8));
}
catch (NoSuchAlgorithmException e)
{
throw new RuntimeException(e);
}
}
However, such a low iteration count may not be sufficient for modern
encryption. For example, RFC 8018 recommends at least 1000 iterations for
PBE[1]. In 2023, OWASP recommended to use 600,000 iterations for
PBKDF2-HMAC-SHA256 and 210,000 for PBKDF2-HMAC-SHA512[2].
Shall we instead use a standard PBKDF with larger iteration count here?
For example:
private SecretKeySpec getSecretKeySpec(String password)
{
int iterationCount = 10000; // Recommended: at least 10,000 iterations
int keyLength = 128; // using 128 bit AES
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt,
iterationCount, keyLength);
SecretKeyFactory factory =
SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256”);
byte[] key = factory.generateSecret(spec).getEncoded();
// Note: using 128 bit AES avoids requirement for "Unlimited
Crypto” patch
return new SecretKeySpec(key, "AES");
}
[1] "PKCS #5: Password-Based Cryptography Specification, Version 2.0"
<http://tools.ietf.org/html/rfc2898#section-5.2>
[2] "Password Storage Cheat Sheet"
<https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2>