AES:如何从每个算法大小的密码生成密钥

时间:2011-09-19 07:44:53

标签: java encryption aes

是否可以编写一个从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编写预定义的盐蚂蚁或使用截断的哈希。

2 个答案:

答案 0 :(得分:2)

如果可以,不要这样做。用户选择的密码通常具有非常差的熵

如果“密码”未由用户选择,而是由加密强 RNG生成,请使用密码或密码哈希。在这种情况下,您不需要PBKDF2。

PBKDF2真的是最后的解决方案。

另请阅读Lessons learned and misconceptions regarding encryption and cryptology

答案 1 :(得分:0)

将256位长度的键截断为所需的大小。密钥应该是随机的,或者使用安全方法(如PBKDF2)生成。如果有疑问,请在截断之前散列更长/均匀随机分布。

您还可以看到PBEKeySpec允许您选择指定密钥长度。