我想在数据库中存储哈希密码(使用BCrypt)。什么是好的类型,哪个是正确的长度?密码是否与BCrypt长度相同?
修改
哈希示例:
$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu
在对某些密码进行哈希处理后,似乎BCrypt总是会生成60个字符的哈希值。
编辑2
很抱歉没有提及实施。我正在使用jBCrypt。
答案 0 :(得分:330)
bcrypt的模块化密码格式由
组成$2$
,$2a$
或$2y$
标识hashing algorithm and format $
.
,/
,0
- 9
,A
- {{ 1}},Z
- a
与standard Base 64 Encoding字母表不同)包括:
因此总长度分别为59或60字节。
当您使用2a格式时,您将需要60个字节。因此对于MySQL,我建议使用CHAR(60) BINARY
or BINARY(60)
(有关差异的信息,请参阅The _bin and binary Collations。)
z
不是二进制安全的,并且等式不仅仅依赖于字节值,而是依赖于实际的整理;在最坏的情况下,CHAR
被视为等于A
。有关详细信息,请参阅The _bin
and binary
Collations。
答案 1 :(得分:47)
Bcrypt哈希可以存储在BINARY(40)
列中。
BINARY(60)
,正如其他答案所暗示的那样,是最简单和最自然的选择,但是如果你想最大化存储效率,你可以通过无损解构散列来节省20个字节。我在GitHub上更详细地记录了这一点:https://github.com/ademarre/binary-mcf
Bcrypt哈希遵循称为模块化密码格式(MCF)的结构。 Binary MCF(BMCF)将这些文本哈希表示解码为更紧凑的二进制结构。在Bcrypt的情况下,生成的二进制散列是40个字节。
Gumbo很好地解释了Bcrypt MCF哈希的四个组成部分:
$<id>$<cost>$<salt><digest>
对BMCF的解码如下:
$<id>$
可以用3位表示。<cost>$
,04-31,可以用5位表示。将这些放在一起1个字节。1 + 16 + 23
您可以在上面的链接中阅读更多内容,或者在GitHub上查看my PHP implementation。
答案 2 :(得分:21)
如果您使用带有PASSWORD_DEFAULT
算法的PHP password_hash()
生成bcrypt哈希(我认为这是很大一部分人阅读此问题),请务必保留请注意,将来password_hash()
可能会使用不同的算法作为默认值,因此可能会影响哈希的长度(但可能不一定会更长)。
从手册页:
请注意,此常量旨在随着时间的推移而变化为新的和 PHP中添加了更强大的算法。出于这个原因,长度 使用此标识符的结果可能会随时间而变化。因此, 建议将结果存储在可以的数据库列中 扩展超过60个字符(255个字符将是一个不错的选择)。
使用bcrypt,即使你有10亿用户(即你目前正在与facebook竞争)存储255字节的密码哈希,它只会有~255 GB的数据 - 大约相当于一个小型SSD硬盘的大小。存储密码哈希极不可能成为应用程序的瓶颈。但是,由于某些原因存储空间确实 的问题,您可以使用PASSWORD_BCRYPT
强制password_hash()
使用bcrypt,即使这不是默认。请务必随时了解bcrypt中发现的任何漏洞,并在每次发布新的PHP版本时查看发行说明。如果更改默认算法,最好查看 why 并做出是否使用新算法的明智决定。
答案 3 :(得分:18)
我不认为你可以做的任何巧妙的技巧存储,例如你可以用MD5哈希。
我认为你最好的选择是将它存储为CHAR(60)
,因为它总是60个字符长