[我正在尝试密钥派生功能,并且发现通过所有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
已编码并不意味着已加密。按照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();