为什么 org.mindrot.JBCrypt 在这里说 Bad salt length?

Why is org.mindrot.JBCrypt saying Bad salt length here?

示例值一千字,希望如此。如果没有,这里有几个测试,在第一个测试中使用盐种子 static seed to be used,在第二个测试中使用 static seed to be usedd 散列纯文本 hello world。 Salt seed 用于生成可以传递给 BCrypt.hashpw(plainText, staticSalt) 函数的静态盐。如您所见,盐字节和盐字节字符串的长度相似,但会引发错误。我知道这不好,但我有我对静态盐的理由,所以请把你的注意力放在这个问题上。

org.mindrot.jbcrypt.BCrypt 与 JDK1.7 测试 1 - PlainText:"hello world",saltseed:"static seed to be used":

Salt bytes for "static seed to be used": [-30, -8, 86, -8, 6, -126, -64, -30, -82, -82, -104, -64, -8, -118, -64, 108, -82, -64, 14, -30, -82, -104]
Salt bytes string: 4vhW+AaCwOKurpjA+IrAbK7ADuKumA==, length: 32
complete salt: avhW+AaCwOKurpjA+IrAbK7ADuKumA==
Exception in thread "main" java.lang.IllegalArgumentException: Bad salt length
at org.mindrot.jbcrypt.BCrypt.crypt_raw(BCrypt.java:619)
at org.mindrot.jbcrypt.BCrypt.hashpw(BCrypt.java:684)

org.springframework.security.crypto.bcrypt.BCrypt 与 JDK1.8 测试 1 - PlainText:"hello world",saltseed:"static seed to be used":

Salt bytes for "static seed to be used": [-30, -8, 86, -8, 6, -126, -64, -30, -82, -82, -104, -64, -8, -118, -64, 108, -82, -64, 14, -30, -82, -104]
Salt bytes string: 4vhW+AaCwOKurpjA+IrAbK7ADuKumA==, length: 32
complete salt: avhW+AaCwOKurpjA+IrAbK7ADuKumA==
Plain text: hello world, Hash text: avhWHrTxEMtyyv6wmpOtX.YYbTqHwHv/dxe

org.mindrot.jbcrypt.BCrypt 与 JDK1.7 测试 2 - PlainText:"hello world",saltseed:"static seed to be usedd":

Salt bytes for "static seed to be usedd": [85, 108, -73, 108, 111, -27, -32, 85, 19, 19, -4, -32, 108, -7, -32, -50, 19, -32, -125, 85, 19, -4]
Salt bytes string: VWy3bG/l4FUTE/zgbPngzhPgg1UT/A==, length: 32
complete salt: a$VWy3bG/l4FUTE/zgbPngzhPgg1UT/A==
Plain text: hello world, Hash text: a$VWy3bG/l4FUTE/zgbPngze9KDSXjF72NBMBNE6ZJk4StahyAhykgO

org.springframework.security.crypto.bcrypt.BCrypt 与 JDK1.8 测试 2 - PlainText:"hello world",saltseed:"static seed to be usedd":

Salt bytes for "static seed to be usedd": [85, 108, -73, 108, 111, -27, -32, 85, 19, 19, -4, -32, 108, -7, -32, -50, 19, -32, -125, 85, 19, -4]
Salt bytes string: VWy3bG/l4FUTE/zgbPngzhPgg1UT/A==, length: 32
complete salt: a$VWy3bG/l4FUTE/zgbPngzhPgg1UT/A==
Plain text: hello world, Hash text: a$VWy3bG/l4FUTE/zgbPngze9KDSXjF72NBMBNE6ZJk4StahyAhykgO

我已经尝试添加和删除更多字母并获得了成功的哈希值。我很高兴 JUnit 测试中使用的第一个字符串抛出了错误。

提前致谢。

我通过查看 GitHub 页面上的实现找到了原因... 此 BCrypt 实现支持 base64 点 (.) 字符而不是标准加号 (+) 字符。

static private final byte index_64[] = {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, 0, 1, 54, 55,
        56, 57, 58, 59, 60, 61, 62, 63, -1, -1,
        -1, -1, -1, -1, -1, 2, 3, 4, 5, 6,
        7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
        17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
        -1, -1, -1, -1, -1, -1, 28, 29, 30,
        31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
        51, 52, 53, -1, -1, -1, -1, -1
};

"+" 字符的整数值为 43,因此 return 是此数组中的 -1,并且从 salt 中断中检索盐字节的函数较早地给我留下了 4 字节的盐。甚至它的实现也说它不支持标准的 base64 编码字符串:

/**
 * Decode a string encoded using bcrypt's base64 scheme to a
 * byte array. Note that this is *not* compatible with
 * the standard MIME-base64 encoding.
 */
static byte[] decode_base64(String s, int maxolen)
        throws IllegalArgumentException {

正在从 . to + 给了我一个与 Spring 不同的散列值,包含 + 的盐。不太熟悉 shift 和 & 来进行更改,因此将寻找 Spring-Security 的实现。

编辑:刚刚查看了 Spring 的实现。难怪它不起作用...除了 Spring 继续使用 4 字节盐进行散列而 jbcrypt 抛出错误外,它完全相同,因此 Spring 中存在错误,而如果您生成自己的散列并且它包含 +,那么 checkpw(plainText, hashedText) 将 return false 因为 hashtedText 生成的盐部分与用户生成的盐不同。