我想在数据库中存储一个哈希密码(使用BCrypt)。 对于此,什么类型是好的,正确的长度是多少? 使用BCrypt散列的密码始终具有相同的长度吗?
编辑
示例哈希:
$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu
一些密码经过哈希后,似乎BCrypt总是生成60个字符的哈希值。
编辑2
很抱歉没有提及实现。 我正在使用jBCrypt。
我想在数据库中存储一个哈希密码(使用BCrypt)。 对于此,什么类型是好的,正确的长度是多少? 使用BCrypt散列的密码始终具有相同的长度吗?
编辑
示例哈希:
$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu
一些密码经过哈希后,似乎BCrypt总是生成60个字符的哈希值。
编辑2
很抱歉没有提及实现。 我正在使用jBCrypt。
bcrypt的模块化密码格式包括:
$2$
、$2a$
或$2y$
,用于标识哈希算法和格式,具体请参见版本历史$
.
、/
、0
–9
、A
–Z
、a
–z
,与标准Base 64编码字母表不同),包括:
因此,总长度分别为59或60个字节。
由于你使用了2a格式,所以需要60个字节。因此,对于MySQL,我建议使用CHAR(60) BINARY
或BINARY(60)
(有关差异的信息,请参见_bin和binary排序规则)。
CHAR
不是二进制安全的,它的相等性不仅取决于字节值,还取决于实际的排序规则;在最坏的情况下,A
被视为等同于 a
。有关更多信息,请参见_bin 和 binary 排序规则。
SQL_Latin1_General_CP1_CS_AS
在MySQL中未知。已知的是latin1_general_cs
。 - Gumbochar
还是具有意外行为的binary(60)
。 - Sir一个Bcrypt哈希可以存储在BINARY(40)
列中。
BINARY(60)
,正如其他答案所建议的那样,是最简单和最自然的选择,但如果您想最大化存储效率,您可以通过无损地分解哈希来节省20个字节。我在GitHub上对此进行了更全面的记录:https://github.com/ademarre/binary-mcf
Bcrypt哈希遵循一种称为模块化加密格式(MCF)的结构。二进制 MCF(BMCF)将这些文本哈希表示解码为更紧凑的二进制结构。在Bcrypt的情况下,生成的二进制哈希是40个字节。
Gumbo很好地解释了Bcrypt MCF哈希的四个组件:
$<id>$<cost>$<salt><digest>
将编码转换为BMCF的方法如下:
$<id>$
可以用3位表示。<cost>$
,04-31,可以用5位表示。将它们放在一起组成1个字节。1 + 16 + 23
您可以在上面的链接中阅读更多信息,或查看我的PHP实现,也可在GitHub上找到。
password_hash()
生成bcrypt哈希值,并且使用PASSWORD_DEFAULT
算法(我认为这是阅读此问题的人的很大一部分),请记住在将来password_hash()
可能会使用不同的算法作为默认值,因此这可能会影响哈希的长度(但它不一定会更长)。PASSWORD_BCRYPT
来强制password_hash()
使用bcrypt,即使这不是默认值。只需确保随时了解bcrypt中发现的任何漏洞并审核每个新的PHP版本的发行说明。如果默认算法发生更改,最好审核原因并做出明智的决定是否使用新算法。我不认为在存储这个内容时有什么巧妙的技巧,就像使用MD5哈希一样。
我认为最好的方法是将其存储为CHAR(60)
,因为它始终是60个字符长。