我正在执行一个Java项目,在该项目中必须确保用户密码保存在纯文本文件中的 secret 性和完整性。
为此,我将仅在文件中写入密码的哈希值。更具体地说,我的意图是编写密码和随机盐的哈希,再加上随机盐本身,以避免使用虹彩表和查找表。我还想对PBKDF2使用 key 拉伸(stretch),以使哈希的计算在计算上变得昂贵。
最后,我想使用 key 哈希算法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();
}
我真正无法理解的是如何输入我的 secret key 作为HMAC算法使用的 key ,因为它似乎不是该函数的输入。我已经阅读了Java文档,但是找不到我的问题的解决方案。
在这一点上,我不确定我是否能正确理解加密机制的不同部分是如何工作的,所以我会接受有关该主题的任何帮助。
最佳答案
我觉得我很困惑。您显然希望您的代码先应用PBKDF2,然后再应用HMAC-SHA-1。这不是它的工作方式:PBKDF2内部使用了HMAC-SHA-1。
PBKDF2的要旨是重复应用具有以下属性的函数:
HMAC-SHA-1是这样的功能,并且是常见的选择。 PBKDF2还有其他变体,它们使用HMAC-MD5,HMAC-SHA-256或其他功能(但是这些变体不在基本Java库中)。
PBKDF2接受两个数据输入(加上一些配置输入):密码和盐。如果要在计算中包括一个 secret 值,请使用PBKDF2的输入:不要在此之上使用自定义方案(使用自己的密码是做错它的秘诀)。将pepper(所有帐户共有的 secret 值)附加到盐(各帐户之间不同的公共(public)值)上。
注意pepper is of limited usefulness。仅当哈希值和Pepper secret 值存储在不同的位置时才有用-例如,如果哈希值在数据库中并且Pepper在不直接受到SQL注入(inject)攻击攻击的磁盘文件中。
关于passwords - 在Java中具有HMAC的PBKDF2,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20047418/