Python bcrypt中'$2a$'的意义是什么?
在网上和StackOverflow上有一些资料可以找到,但它们似乎有些矛盾,也不够完整。
所以我想问的是:
在python-bcrypt中,前面加上的$2a$有什么重要意义?
我具体使用的是这个实现:http://www.mindrot.org/projects/py-bcrypt/,但这个问题是普遍适用的。
另外,能否说明一下在python-bcrypt模块中,这个设置是否可以配置?还有是否真的存在安全问题,导致你需要使用某个特定的不同实现。
1 个回答
$2a$
是用来表示所使用的算法的标识符。
在 OpenBSD 的密码文件中,有一些标准用于存储密码。每个密码前面都有一个 算法标识符。
$1$
: MD5 哈希$2$
: bcrypt 哈希$5$
: SHA2-256 哈希$6$
: SHA2-512 哈希
BCrypt 变种
当 bcrypt 最初发布时,它的标识符是 $2$
。
$2$
BCrypt 是由 OpenBSD 的团队设计的,目的是为了在 OpenBSD 的密码文件中存储密码的哈希值。哈希后的密码会加上一个前缀,以便识别所使用的算法。BCrypt 的前缀是 $2$
。
$2a$
最初的 BCrypt 规范没有定义如何处理非 ASCII 字符,也没有说明如何处理空字符终止符。后来规范进行了修订,明确规定在哈希字符串时:
- 字符串必须是 UTF-8 编码
- 必须包含空字符终止符
$2x$, $2y$ (2011年6月)
发现了一个 bug,在 crypt_blowfish 中,这是一个 PHP 实现的 BCrypt。它错误地处理了第 8 位被设置的字符。
建议系统管理员更新他们现有的密码数据库,将 $2a$
替换为 $2x$
,以表示这些哈希是有问题的(需要使用旧的有缺陷的算法)。他们还建议 crypt_blowfish 对修复后的算法生成的哈希使用 $2y$
。但包括 OpenBSD 在内的其他人并没有采纳 2x
/2y
的想法。这个版本标记仅限于 crypt_blowfish。
版本 $2x$ 和 $2y$ 并不是比 $2a$ “更好”或“更强”。它们只是某个特定有缺陷的 BCrypt 实现的遗留物。
$2b$ (2014年2月)
在 OpenBSD 的 BCrypt 实现中发现了一个 bug。他们将字符串的长度存储在一个 unsigned char
中。如果密码超过 255 个字符,就会溢出并在 255 处回绕。
BCrypt 是为 OpenBSD 创建的。当他们的库出现 bug 时,他们决定可以更新版本。这意味着如果你想跟上“他们”的规范,其他人也需要这样做。
- http://undeadly.org/cgi?action=article&sid=20140224132743
- http://marc.info/?l=openbsd-misc&m=139320023202696
版本 $2b$ 并不是比 $2a$ “更好”或“更强”。它只是某个特定有缺陷的 BCrypt 实现的遗留物。但由于 BCrypt 正式归 OpenBSD 所有,他们可以随意更改版本标记。
2a、2x、2y 和 2b 之间没有区别。如果你的实现是正确的,它们的输出结果都是一样的。
如果你从一开始就做对了(以 utf8 存储字符串并且哈希空字符终止符),那么:2、2a、2x、2y 和 2b 之间没有区别。如果你的实现是正确的,它们的输出结果都是一样的。
只有那些可能使用过 crypt_blowfish 的人需要关心 2x 和 2y。而只有那些可能在运行 OpenBSD 的人需要关心 2b。
其他所有正确的实现都是相同且正确的。