BCrypt 哈希值string好像:
$2a$10$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm
\__/\/ \____________________/\_____________________________/
| | Salt Hash
| Cost
Version
Where
-
2a
:算法标识符(BCrypt,UTF8编码密码,以null结尾)
-
10
: Cost Factor (210
= 1,024 rounds)
-
Ro0CUfOqk6cXEKf3dyaM7O
:OpenBSD-Base64 编码盐(16 字节 ⇒ 22 个字符)
-
hSCvnwM9s4wIX9JeLapehKK5YdLxKcm
:OpenBSD-Base64 编码散列(24 字节 ⇒ 31 个字符)
Edit: 我刚刚注意到这些词完全合适。我必须分享:
$2a$10$TwentytwocharactersaltThirtyonecharacterspasswordhash
$==$==$======================-------------------------------
BCrypt does使用 16 字节 salt 创建 24 字节二进制哈希。您可以随意存储二进制哈希值和盐;你什么也没说have将其以 base-64 编码为字符串。
But BCrypt是由从事 OpenBSD 工作的人创建的。OpenBSD已经定义了他们的密码文件的格式:
$[HashAlgorithmIdentifier]
$[AlgorithmSpecificData]
这意味着“bcrypt 规范”与 OpenBSD 密码文件格式有着千丝万缕的联系。每当有人创建一个“bcrypt 哈希” they always将其转换为以下格式的 ISO-8859-1 字符串:
$2a
$[Cost]
$[Base64Salt][Base64Hash]
几个要点:
-
2a
是算法标识符
- 1: MD5
- 2:早期的 bcrypt,对密码的编码方式存在混淆(已过时)
- 2a:当前bcrypt,指定密码为UTF-8编码
-
Cost是计算哈希值时使用的成本因素。 “当前”值为 10,表示内部密钥设置经过 1,024 轮
- 10: 210 = 1,024 iterations
- 11: 211 = 2,048 iterations
- 12: 212 = 4,096 iterations
-
OpenBSD 密码文件使用的 Base64 算法与以下的 Base64 编码不同:其他人用途;他们有自己的:
Regular Base64 Alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
BSD Base64 Alphabet: ./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
因此 bcrypt 的任何实现都不能使用任何内置或标准的 base64 库
有了这些知识,您现在可以验证密码correctbatteryhorsestapler
针对保存的哈希:
$2a$12$mACnM5lzNigHMaf7O1py1O3vlf6.BA8k8x3IoJ.Tq3IB/2e7g61Km
BCrypt 变体
bcrypt 版本存在很多混乱。
$2$
BCrypt 是由 OpenBSD 人员设计的。它旨在对密码进行哈希处理以存储在 OpenBSD 密码文件中。哈希密码以前缀存储,以识别所使用的算法。 BCrypt 得到了前缀$2$
.
这与其他算法前缀形成对比:
-
$1$
: MD5
-
$5$
:SHA-256
-
$6$
:SHA-512
$2a$
最初的 BCrypt 规范没有定义如何处理非 ASCII 字符,或者如何处理空终止符。该规范经过修订,指定在对字符串进行哈希处理时:
$2x$, $2y$ (2011 年 6 月)
A bug was discovered in crypt_blowfish https://en.wikipedia.org/wiki/Bcrypt#Versioning_history???? https://archive.fo/CnnUz, a PHP implementation of BCrypt. It was mis-handling characters with the 8th bit set.
They suggested that system administrators update their existing password database, replacing $2a$
with $2x$
, to indicate that those hashes are bad (and need to use the old broken algorithm). They also suggested the idea of having crypt_blowfish emit $2y$
for hashes generated by the fixed algorithm. Nobody else, including canonical OpenBSD, adopted the idea of 2x
/2y
. This version marker was was limited to crypt_blowfish http://seclists.org/oss-sec/2011/q2/632???? https://archive.fo/tqDGj.
版本$2x$ and $2y$并不比“更好”或“更强”$2a$。它们是 BCrypt 的一种特定的有缺陷的实现的残余。
$2b$ (2014 年 2 月)
在 BCrypt 的 OpenBSD 实现中发现了一个错误。他们用不支持字符串的语言编写实现 - 因此他们用长度前缀、指向字符的指针来伪造它,然后用[]
。不幸的是,他们将字符串的长度存储在一个unsigned char
。如果密码长度超过 255 个字符,它将溢出并在 255 处换行。BCrypt 是为 OpenBSD 创建的。当他们遇到错误时their图书馆,他们决定可以升级版本。这意味着如果您想保持最新状态,其他人都需要效仿"their"规格。
-
???? https://archive.fo/ZjV9P
-
???? https://archive.fo/J7dRp
之间没有区别2a, 2x, 2y, and 2b。如果您正确编写了实现,它们都会输出相同的结果。
- 如果您从一开始就做正确的事情(以 utf8 存储字符串并散列空终止符),那么:2, 2a, 2x, 2y, and 2b。如果您正确编写了实现,它们都会输出相同的结果。
- 版本$2b$并不比“更好”或“更强”$2a$。它是 BCrypt 的一个特定的有缺陷的实现的残余。但由于 BCrypt 按照规范属于 OpenBSD,因此他们可以将版本标记更改为他们想要的任何内容。
- 版本$2x$ and $2y$并不比任何事情更好,甚至更可取。它们是有缺陷的实现的残余物 - 应该立即被遗忘。
唯一需要关心 2x 和 2y 的人是那些您可能一直在使用的人地穴河豚回到2011年。唯一需要关心的人2b那些可能一直在运行 OpenBSD 的人。
所有其他正确的实现都是相同且正确的。