jBCrypt serious issue with checkpw (return true when it shouldn't?)
编辑:好的,所以我在这里找到了答案。BCrypt说,很长一段时间,类似的密码是等效的-我,gem或密码学领域有问题吗?
但是,这是一个新问题,如果在我们试图教育用户选择越来越复杂的密码(甚至密码)的世界中,如果您必须限制用户的密码长度,那么有人建议使用bCrypt进行哈希运算,说您的密码必须短于n个字符似乎是一种结束于thedailywtf.com星期五屏幕截图的方法:)
以下是原始问题:
我正在为应用程序重构旧的登录页面,并决定使用JAVA实现jBCrypt(http://www.mindrot.org/projects/jBCrypt/)来给bCrypt一个旋转,并遇到了一个主要的显示停止器。
问题是checkpw方法,使用长种子时似乎总是返回true。我将使用{InternalSalt} {username} {password}设置用户密码,然后使用bCrypt对其进行哈希处理。
所以我有以下代码(尽可能将其剥离以隔离checkpw)。
1 2 3 4 5 6 7 8 9 10 11 12 | 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"); } |
}
这将按要求打印" It match"。
我遇到的问题是说您在传递给checkpw的密码中添加了aaa
BCrypt.checkpw(" jw?ct / f61y1m7q458GiLVQpiqDK | 8kG = d368Id:D @ $ ^ _ 80I {qrn1HM6423 {FtestAccountO1nu3jKNaaa",pw_hash)
它仍然返回true!不完全是我的期望。我在文档中没有看到任何密码长度限制,但是无法使用较小的密码种子来重现它,而且看起来如果我修改了除字符串末尾以外的任何内容,它会按预期返回false。
我错过了重要的事情吗?我知道我一定不是在这些论坛上唯一使用jBcrypt的人,因为我在做一些研究时在许多帖子中都看到了BCrypt的建议。
编辑:Windows 7 64位-Java(TM)SE运行时环境(内部版本1.6.0_24-b07)
好的,这样的措辞使我有足够的能力来真正弄清楚我要寻找的东西(橡皮鸭的欢呼声)。密码学领域现在是安全的!
BCrypt使用P_orig进行XOR,它是18个4个字节的整数,直到结束为止,这将您的加密"密钥"限制为72个字节。 72个字节后的Eveyrything将被忽略(警告会很好)。
似乎可以接受的折衷办法不是将用户密码限制为72个字符或更少,而只是让其静默通过。无论如何,背后的想法是使用72个字符的bCrypted密码比快速哈希替代方法更好。
资料来源:BCrypt说,很长一段时间,类似的密码是等效的-我,gem或密码学领域有问题吗?
实际上,您自己的答案很棒,并帮助我找到了令人讨厌的问题;)对于在哈希之前向普通用户添加某种应用程序秘密的人(即使他们限制了密码长度),有一些技巧:特别是在最后添加应用程序秘密如果应用程序的机密长度为72个字符-否则每次匹配都会返回
所以与其:
采用:
即使发生Bcrypt的裁剪,