有没有可能编写一个单独的方法,从密码中生成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);
}
所以我只能使用另一个构造函数,该函数需要一个盐作为参数:
KeySpec ks = new PBEKeySpec(password.toCharArray(), "somepredefinedsalt".getBytes(), numIters, keySizeInBits);
由于我没有盐值,所以我考虑硬编码一个预定义的盐值。现在我不知道哪个选项更安全,是编写一个预定义的盐值并使用PBKDF2呢,还是使用截断哈希。