SecretKey.getEncoded()为何返回PBE生成的密钥的明文密码?

问题描述 投票:2回答:1

[我正在尝试密钥派生功能,并且发现通过所有PBE算法生成的秘密密钥都编码为纯文本密码。

[我的意思是:

public class Main {
    public static void main(String[] args) throws Exception {
        byte[] salt = new byte[256/8];
        SecureRandom.getInstanceStrong().nextBytes(salt);
        KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, /*iterations*/ 1000, /*key length*/ 1024);
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithHMACSHA512AndAES_256"); // PBE with HMAC SHA512 and AES_256
        SecretKey secret = factory.generateSecret(spec);
        System.out.println(new String(secret.getEncoded()));
    }
}

prints password,我期望1024个看似随机的字节。这对我来说还不算是..你能解释一下吗?

BTW:请注意,相同的代码似乎确实可以与PBKDF2算法一起使用。

PS:万一重要,我在Mac(13.0.1.hs-adpt)上使用香草OpenJDK 13

java password-hash
1个回答
0
投票

已编码并不意味着已加密。按照Key类的javadoc getEncoded()方法返回键的表示形式:

 * This is an external encoded form for the key used when a standard
 * representation of the key is needed outside the Java Virtual Machine,
 * as when transmitting the key to some other party. The key
 * is encoded according to a standard format (such as
 * X.509 {@code SubjectPublicKeyInfo} or PKCS#8), and
 * is returned using the {@link #getEncoded() getEncoded} method.

由于PBEWithHMACSHA512AndAES_256是对称算法,因此观察到的行为是有意义的。相同的密钥用于执行加密和解密,无法修改。

[看How do I properly use the “PBEWithHmacSHA512AndAES_256” algorithm?问题。您需要使用正确的byte[] messageBytes实例对Cipher下的输入进行加密:

Cipher cipherEncrypt = Cipher.getInstance("PBEWithHMACSHA512AndAES_256");
cipherEncrypt.init(Cipher.ENCRYPT_MODE, key);

byte[] cipherBytes = cipherEncrypt.doFinal(messageBytes);
byte[] iv = cipherEncrypt.getIV();
© www.soinside.com 2019 - 2024. All rights reserved.