6

我正在开发一个 Java 项目,我必须确保保存在纯文本文件中的用户密码的机密性和完整性。

为此,我将只在文件中写入密码的哈希值。更具体地说,我的意图是编写密码的哈希值和随机盐,加上随机盐本身,以避免使用彩虹表和查找表。我还想对 PBKDF2 使用键拉伸,以使哈希的计算在计算上变得昂贵。最后,我想使用密钥哈希算法 HMAC 作为最后一层保护。

我正在尝试在 Java 代码中实现我的想法,并且我找到了一些上面介绍的操作示例:

private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes)
    throws NoSuchAlgorithmException, InvalidKeySpecException
{
    PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
    SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    return skf.generateSecret(spec).getEncoded();
}

我真正无法理解的是如何输入我的密钥作为 HMAC 算法使用的密钥,因为它似乎不是函数的输入。我浏览了 Java 文档,但找不到我的问题的解决方案。

在这一点上,我不确定我是否正确理解了加密机制的不同部分是如何工作的,所以我会接受有关该主题的任何帮助。

4

1 回答 1

13

我想我看到了混乱。您显然希望您的代码先应用 PBKDF2,然后再应用 HMAC-SHA-1。这不是它的工作原理:HMAC-SHA-1 在 PBKDF2 中使用。

PBKDF2的要点是重复应用具有以下属性的函数:

  • 它需要两个参数;
  • 它返回一个固定大小的值;
  • 它实际上与伪随机函数无法区分。

HMAC-SHA-1 就是这样一个函数,也是一个常见的选择。PBKDF2 还有其他变体,使用 HMAC-MD5、HMAC-SHA-256 或其他函数(但这些变体不在基本 Java 库中)。

PBKDF2 接受两个数据输入(加上一些配置输入):密码和盐。如果你想在计算中包含一个秘密值,那么 PBKDF2 的输入就是它的地方:不要在此之上附加自定义方案(做你自己的加密是做错的秘诀)。将胡椒(所有帐户通用的秘密值)附加到盐(帐户之间变化的公共值)。

请注意,胡椒的用处有限。仅当哈希值和辣椒秘密值存储在不同的位置时才有用——例如,如果哈希值在数据库中,而辣椒值在不易受到 SQL 注入攻击的磁盘文件中。

于 2013-11-18T10:49:13.803 回答