为什么“$2a”与“$2b”很重要?

Why would "$2a" vs "$2b" matter?

我试图编写一个脚本来将用户添加到 MySQL 数据库中。我终于让所有用户都进入了数据库,但是我的应用程序的登录不会授权他们。我尝试了一系列不同的解决方案,然后我注意到老用户的密码以“$2a”开头,而我添加的密码是“$2b”。所以我在下面插入代码。

password = bcrypt.hashpw(password.encode("UTF-8"), bcrypt.gensalt(11))
password = password.decode("UTF-8")
password = password[:2] + "a" + password[3:] #Why does this work??

突然可以登录了。那么为什么使用“$2a”而不是“$2b”呢?该网络应用程序不是我的,我找不到检查密码的代码。如果有帮助,webapp 是在 Java 中制作的,并使用 spring 进行验证。

这里是Wikipedia on Bcrypt

$ (1999)

The original Bcrypt specification defined a prefix of $. This follows the Modular Crypt Format [...]

a$

The original specification did not define how to handle non-ASCII character, nor how to handle a null terminator. The specification was revised to specify that when hashing strings:

  • the string must be UTF-8 encoded
  • the null terminator must be included
  • With this change, the version was changed to a$

b$ (February 2014)

A bug was discovered in the OpenBSD implementation of bcrypt. They were storing the length of their strings in an unsigned char (i.e. 8-bit Byte). If a password was longer than 255 characters, it would overflow and wrap at 255.

您正在添加新格式,而程序仅支持验证旧格式。

由于新旧格式兼容小于 255 个字符的密码,因此切换 header 有效。但是,如果您尝试以这种方式添加 >= 256 个字符的密码,它将被视为无效而被拒绝。