我正在做一个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 文档,但我找不到我的问题的解决方案。
在这一点上,我不确定我是否正确理解了加密机制的不同部分是如何工作的,所以我会接受有关该主题的任何帮助。
我想我看到了混乱。您显然希望您的代码应用 PBKDF2,然后应用 HMAC-SHA-1。这不是它的工作原理:HMAC-SHA-1在PBKDF2中使用。
PBKDF2 的要点是重复应用具有以下属性的函数:
- 它需要两个参数;
- 它返回一个固定大小的值;
- 它实际上与伪随机函数没有区别。
HMAC-SHA-1就是这样的功能,也是常见的选择。PBKDF2还有其他变体,使用HMAC-MD5,HMAC-SHA-256或其他函数(但这些变体不在基本的Java库中)。
PBKDF2 接受两个数据输入(加上一些配置输入):密码和盐。如果你想在计算中包含一个秘密值,PBKDF2的输入就是它的地方:不要在此基础上附加一个自定义方案(做自己的加密是做错的秘诀)。将辣椒(所有帐户通用的秘密值)附加到盐(帐户之间的公共值不同)。
请注意,胡椒的用处有限。仅当哈希和 pepper 秘密值存储在不同位置时,它才有用 - 例如,如果哈希位于数据库中,并且 pepper 位于不直接容易受到 SQL 注入攻击的磁盘文件中。