Java 为什么SecretKey.getEncoded()返回PBE生成的密钥的明文密码?
我正在试验密钥派生函数,我注意到我通过所有PBE算法生成的密钥都编码为纯文本密码 我的意思是:Java 为什么SecretKey.getEncoded()返回PBE生成的密钥的明文密码?,java,password-hash,Java,Password Hash,我正在试验密钥派生函数,我注意到我通过所有PBE算法生成的密钥都编码为纯文本密码 我的意思是: 公共类主{ 公共静态void main(字符串[]args)引发异常{ 字节[]salt=新字节[256/8]; SecureRandom.getInstanceStrong().nextBytes(salt); KeySpec spec=new-PBEKeySpec(“password.toCharArray(),salt,/*迭代次数*/1000,/*密钥长度*/1024); SecretKeyF
公共类主{
公共静态void main(字符串[]args)引发异常{
字节[]salt=新字节[256/8];
SecureRandom.getInstanceStrong().nextBytes(salt);
KeySpec spec=new-PBEKeySpec(“password.toCharArray(),salt,/*迭代次数*/1000,/*密钥长度*/1024);
SecretKeyFactory factory=SecretKeyFactory.getInstance(“PBEWithHMACSHA512AndAES_256”);//带有HMAC SHA512和AES_256的PBE
SecretKey secret=factory.generateSecret(规范);
System.out.println(新字符串(secret.getEncoded());
}
}
打印password
,其中我希望显示1024个看似随机的字节。这对我来说不太合适。。你能解释一下吗
顺便说一句:请注意,相同的代码似乎与我预期的PBKDF2算法一样有效
PS:如果有关系,我在mac上使用香草OpenJDK 13(13.0.1.hs adpt)编码并不意味着加密。根据
Key
classjavadocgetEncoded()
方法返回键的表示形式:
*这是一种外部编码形式,用于标准配置时使用的密钥
*需要在Java虚拟机之外表示密钥,
*就像把钥匙传给另一方一样。钥匙
*根据标准格式进行编码(例如
*X.509{@code SubjectPublicKeyInfo}或PKCS#8),以及
*使用{@link#getEncoded()getEncoded}方法返回。
由于PBEWithHMACSHA512AndAES_256
是一种对称算法,因此观察到的行为是有意义的。同一密钥用于执行加密和解密,不能修改
看看这个问题。您需要使用正确的密码
实例对字节[]消息字节
下面的输入进行加密:
Cipher cipherEncrypt = Cipher.getInstance("PBEWithHMACSHA512AndAES_256");
cipherEncrypt.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherBytes = cipherEncrypt.doFinal(messageBytes);
byte[] iv = cipherEncrypt.getIV();
你用的是什么提供商,BouncyCastle?。如果是BC,那么您通常会使用SecretKeyFactory.getInstance(“algo”,“provider”),您的问题可能是providerdependent@NigelSavage感谢您的来电–我在Machine上使用的是香草openjdk 13(13.0.1.hs adpt),我想您可能已经发现了一个bug,所有内容都检查了您的代码“pbewithhmacsha512andaes256”是由SunJCE提供商提供的,我可以在openjdk11上重现您的问题,据我所知,代码的工作原理应该与PBKDF2相同?我认为它实际上使用的是您提供的密钥,而不是派生密钥,当然它的name.IDK中没有任何关于密钥派生的提示,但我认为PBE算法是PKCS#5加密方案的推广(参见rfc8018)。也许我不明白的一点是为什么
PBEKeySpec
的构造函数需要salt,迭代次数和所需的关键帧长度(如果忽略)。