6

编辑:好的,所以我在这里找到了一个答案BCrypt 说很长,类似的密码是等效的 - 我的问题,宝石或密码学领域?

不过,新问题是,如果在我们试图教育用户选择越来越复杂的密码甚至密码短语的世界中,如果您必须限制用户的密码长度,那么有人如何推荐使用 bCrypt 进行散列,说您的密码必须短于 n 个字符似乎是在 thedailywtf.com 周五的截图中结束的一种方式:)

下面的原始问题:

我正在为一个应用程序重构一个旧的登录页面,并决定使用 JAVA 实现 jBCrypt ( http://www.mindrot.org/projects/jBCrypt/ ) 给 bCrypt 一个旋转,并遇到了一个主要的显示停止器。

问题在于checkpw方法,当使用很长的种子时,它似乎总是返回 true。我打算用 {InternalSalt}{username}{password} 对用户的密码加盐,然后用 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");

}

}

这将打印“它匹配”。

我遇到的问题是说您将say aaa添加到您传递给checkpw 的密码中

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)

4

2 回答 2

5

好的,所以这个问题的措辞足以让我真正弄清楚我在寻找什么(为橡皮擦而欢呼)。密码学领域现在是安全的!

BCrypt 使用 P_orig 实现 XOR,它是 18 个 4 字节整数,直到它到达末尾,这将您的加密“密钥”限制为 72 个字节。72 字节之后的所有内容都被忽略(警告会很好)。

似乎被接受的妥协不是将用户的密码限制在 72 个字符或更少,而只是让它静默通过。这背后的想法是 72 个字符的 bCrypted 密码无论如何都比快速散列替代方案更好。

资料来源:BCrypt 说长而相似的密码是等效的 - 我的问题,gem,还是密码学领域?

于 2011-05-30T19:44:39.010 回答
2

实际上,您自己的答案很棒,并帮助我找到了烦人的问题;)对于在散列之前将某种应用程序的秘密添加到纯文本的人有一些提示(即使他们限制了密码长度):尤其是在末尾包含应用程序秘密如果应用程序的秘密是 72 个字符长 - 否则每次点击都会返回true

所以与其:

String hashed = BCrypt.hashpw(APP_SECRET + plain, BCrypt.gensalt())

利用:

String hashed = BCrypt.hashpw(plain + APP_SECRET, BCrypt.gensalt())

即使发生 Bcrypt 的裁剪,checkpw结果也是有效的!

于 2014-11-08T14:51:25.273 回答