Java SecretKeyFactory 生成的密钥与输入的密码相同

Java SecretKeyFactory generated key is same as input password

我正在尝试使用 PBE 生成密钥,但 SecretKeyFactory 生成的密钥与输入的密码完全相同。我已经尝试了不同的算法、迭代计数等,但它仍然是一样的,所以我觉得我在这里错过了一步。

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"); 
}

编辑:如果我使用算法 "PBKDF2WithHmacSHA1" 那么生成的密钥与密码不同,但我使用的算法为什么会生成与输入密码完全相同的密钥?

当您使用 SecretKeyFactory PBEWithHmacSHA256AndAES_128 生成 SecretKey 时,您将获得 com.sun.crypto.provider.PBEKey 的实例,并且此 class 具有 "special feature" returns 调用 getEncoded() 时的原始 "key" (又名密码)而不是加密密钥 material。如果我理解正确的话,密钥推导不会由 KeyFactory 而是由 Cipher 本身进行。

因此,您不应尝试将 SecretKey 实例转换为 SecretKeySpec 实例;而只是在正确的密码实例中使用生成的 SecretKey 实例:

Cipher c = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
c.init(Cipher.ENCRYPT_MODE, secretKey);