问题
I'm trying to generate a secret key using PBE but the secret key generated by the SecretKeyFactory is exactly the same as the input password. I've tried different algorithms, iteration counts etc. and it is still the same so I feel I'm missing a step here.
public SecretKey generateKey(String password, String salt) {
char[] passChars = password.toCharArray();
byte[] saltBytes = salt.getBytes();
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_128");
PBEKeySpec keySpec = new PBEKeySpec(passChars, saltBytes, 2048, 128);
SecretKey secretKey = keyFactory.generateSecret(keySpec);
byte[] encodedKey = secretKey.getEncoded();
System.out.println("key: " + new String(encodedKey));
return new SecretKeySpec(encodedKey, "AES");
}
EDIT: if I use the algorithm "PBKDF2WithHmacSHA1" then the key generated is different from the password, but how come the algorithm I'm using is generating a key that is exactly the same as the input password?
回答1:
When you generate a SecretKey
using the SecretKeyFactory PBEWithHmacSHA256AndAES_128
you will get an instance of com.sun.crypto.provider.PBEKey
and this class has the "special feature" that it returns the original "key" (aka password) when calling getEncoded()
and not the cryptographic key material. If I understand it correctly the key derivation will not be made by the KeyFactory but by the Cipher itself.
Therefore you should not try to convert the SecretKey
instance into a SecretKeySpec
instance; instead just use the generated SecretKey
instance in the correct cipher instance:
Cipher c = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
c.init(Cipher.ENCRYPT_MODE, secretKey);
来源:https://stackoverflow.com/questions/39954211/java-secretkeyfactory-generated-key-is-same-as-input-password