是否可以编写一个从AES-128,AES-192和AES-256密码生成有效密钥的方法?
我正在考虑这样的事情:
SecretKeyFactory f;
try {
f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
throw new Exception("Key derivation algorithm not available.", e);
}
KeySpec ks = new PBEKeySpec(password.toCharArray());
SecretKey s;
try {
s = f.generateSecret(ks);
} catch (InvalidKeySpecException e) {
throw new Exception("Key generation failed.", e);
}
Key k = new SecretKeySpec(s.getEncoded(),"AES");
我使用类似的方法为AES-256生成盐渍密钥。但是,现在我必须从密码生成密钥(没有盐和没有迭代),我需要它们用于AES-128,AES-192和AES-256。我的问题是,此代码是否返回与每个AES-XXX大小兼容的密钥,还是应该为每个大小编写不同的代码?
此外,是否有更好的(在安全性或简单性方面)从密码生成密钥的方式?
更新:最后我做了一些测试,结果发现这个构造函数:
KeySpec ks = new PBEKeySpec(password.toCharArray());
始终在此块上抛出InvalidKeySpecException:
try {
s = f.generateSecret(ks);
} catch (InvalidKeySpecException e) {
throw new Exception("Key generation failed.", e);
}
所以我坚持使用另一个构造函数,它需要一个salt作为参数:
KeySpec ks = new PBEKeySpec(password.toCharArray(), "somepredefinedsalt".getBytes(), numIters, keySizeInBits);
因为我没有盐,所以我想硬编码预定义的。现在我不知道哪个选项更安全,使用PBKDF2编写预定义的盐蚂蚁或使用截断的哈希。
答案 0 :(得分:2)
如果可以,不要这样做。用户选择的密码通常具有非常差的熵。
如果“密码”未由用户选择,而是由加密强 RNG生成,请使用密码或密码哈希。在这种情况下,您不需要PBKDF2。
PBKDF2真的是最后的解决方案。
另请阅读Lessons learned and misconceptions regarding encryption and cryptology
答案 1 :(得分:0)
将256位长度的键截断为所需的大小。密钥应该是随机的,或者使用安全方法(如PBKDF2)生成。如果有疑问,请在截断之前散列更长/均匀随机分布。
您还可以看到PBEKeySpec允许您选择指定密钥长度。