EDIT:好吧,我在这里找到了一个答案BCrypt说长的、相似的密码是等价的——我、宝石还是密码学领域的问题?
不过,新的问题是,如果你必须限制用户的密码长度,在我们试图教育用户选择越来越复杂的密码,甚至是密码短语的世界里,说你的密码必须短于n个字符,那么有人怎么能建议你使用bCrypt进行哈希呢?这似乎是一种最终出现在每日邮报周五截图中的方式:)
下面的原始问题:
我正在为一个应用程序重构一个旧的登录页面,并决定使用JAVA实现jBCrypt来试用bCrypt(http://www.mindrot.org/projects/jBCrypt/)并撞上了一个主要的节目主持人。
问题是checkpw方法,当使用非常长的种子时,该方法似乎总是返回true。我打算用{InternalSalt}{username}{password}对用户的密码进行salt处理,然后用bCrypt对其进行哈希处理。
因此,我有以下代码(尽可能精简它以隔离checkpw)。
public class Test {
public static void main(String[] args) {
String plaintext = "jw~ct/f61y1m7q458GiLVQpiqDK|8kG=d368Id:D@$^_80I{qrn1HM6423{FtestAccountO1nu3jKN";
String pw_hash = BCrypt.hashpw(plaintext, BCrypt.gensalt());
if (BCrypt.checkpw("jw~ct/f61y1m7q458GiLVQpiqDK|8kG=d368Id:D@$^_80I{qrn1HM6423{FtestAccountO1nu3jKN", pw_hash))
System.out.println("It matches");
else
System.out.println("It does not match");
}
}
这将打印"匹配"。
我遇到的问题是,假设你在传递给checkpw的密码中添加sayaaa,使其成为
BCrypt.checkpw("jw~ct/f61y1m7q458GiLVQpiqDK|8kG=d368Id:D@$^_80I{qrn1HM6423{FtestAccountO1nu3jKNaaa",pw_hash)
它仍然是真的!不完全是我所期望的。我在文档中没有看到任何密码长度限制,但我无法用较小的密码种子复制它,而且如果我修改了字符串末尾以外的任何内容,它也会按预期返回false。
我错过了什么重要的东西吗?我知道我一定不是唯一一个在这些论坛上使用jBcrypt的人,因为我在做一些研究时看到了许多帖子中推荐的BCrypt。
编辑:Windows 7 64位-Java(TM)SE运行时环境(内部版本1.6.0_24-b07)
好的,所以这个问题的措辞让我能够真正弄清楚我在寻找什么(为橡胶躲避欢呼)。密码学领域目前是安全的!
BCrypt实现XOR使用p_orig,它是18 4字节的整数,直到它到达末尾,这将您的加密"密钥"限制为72字节。72字节之后的每一个字节都被忽略(如果有警告就好了)。
似乎可以接受的折衷方案不是将用户的密码限制在72个字符或更少,而是让它安静地通过。这背后的想法是,72个字符的b加密密码无论如何都比快速哈希替代方案要好。
来源:BCrypt说长的、相似的密码是等价的——我、宝石还是密码学领域的问题?
实际上,您自己的答案是很棒,并帮助我找到了令人讨厌的问题;)对于那些在哈希之前将某种应用程序的秘密添加到明文中的人(即使他们限制了密码长度),有一些建议:在末尾包含应用程序秘密,特别是如果应用程序的机密长度为72个字符,否则每次点击都会返回true
!
因此:
String hashed = BCrypt.hashpw(APP_SECRET + plain, BCrypt.gensalt())
用途:
String hashed = BCrypt.hashpw(plain + APP_SECRET, BCrypt.gensalt())
即使Bcrypt的裁剪将发生,checkpw
结果也将有效!