Is it possible to write a single method that generates valid keys from a password for AES-128, AES-192, and AES-256?
I'm thinking in something like this:
SecretKeyFactory f;
try {
f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
throw new Exception("Key derivation algorithm not available.", e);
}
KeySpec ks = new PBEKeySpec(password.toCharArray());
SecretKey s;
try {
s = f.generateSecret(ks);
} catch (InvalidKeySpecException e) {
throw new Exception("Key generation failed.", e);
}
Key k = new SecretKeySpec(s.getEncoded(),"AES");
I was using a similar approach to generate salted keys for AES-256. However, now I have to generate keys just from a password (with no salt and no iterations), and I need them to work for AES-128, AES-192 and AES-256. My question is, does this code return keys compatible with every AES-XXX size, or should I write different code for each size?
Also, is there a better (in terms of security or simplicity) way of generating a key from a password?
UPDATE: Finally I made some tests and it turns out that this constructor:
KeySpec ks = new PBEKeySpec(password.toCharArray());
Always throws an InvalidKeySpecException
on this block:
try {
s = f.generateSecret(ks);
} catch (InvalidKeySpecException e) {
throw new Exception("Key generation failed.", e);
}
So I'm stuck with the other constructor, that needs a salt as a parameter:
KeySpec ks = new PBEKeySpec(password.toCharArray(), "somepredefinedsalt".getBytes(), numIters, keySizeInBits);
As I don't have a salt, I've thought of hardcoding a predefined one. Now I don't know which option is more secure, coding a predefined salt and using PBKDF2 or using a truncated hash.
If you can, do not do that. A user selected password typically has very poor entropy.
If the "password" is not user selected, but instead produced by a cryptographically strong RNG, use the password, or a hash of the password. In this case, you do not need PBKDF2.
PBKDF2 is really the last resort solution.
Please also read Lessons learned and misconceptions regarding encryption and cryptology