我想在数据库中存储哈希密码(使用BCrypt)。什么是一个好的类型,哪个是正确的长度?用BCrypt散列的密码是否总是相同长度?
编辑
哈希示例:
$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu
在对一些密码进行哈希处理之后,BCrypt似乎总是生成60个字符的哈希。
编辑2
很抱歉没有提及实施。我正在使用jBCrypt。
我想在数据库中存储哈希密码(使用BCrypt)。什么是一个好的类型,哪个是正确的长度?用BCrypt散列的密码是否总是相同长度?
编辑
哈希示例:
$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu
在对一些密码进行哈希处理之后,BCrypt似乎总是生成60个字符的哈希。
编辑2
很抱歉没有提及实施。我正在使用jBCrypt。
Answers:
bcrypt的模块化crypt格式包括
$2$
,$2a$
或$2y$
识别哈希算法和格式$
.
,/
,0
- 9
,A
- Z
,a
- z
也就是不同的标准Base 64编码字母表)由以下组成:
因此,总长度分别为59或60个字节。
使用2a格式时,需要60个字节。因而对于MySQL的,我会建议使用CHAR(60) BINARY
或BINARY(60)
(见的_bin和二进制排序规则有关的差异信息)。
CHAR
不是二进制安全的,相等性不仅仅取决于字节值,还取决于实际的排序规则;在最坏的情况下A
被视为等于a
。见的_bin
和binary
排序规则以获取更多信息。
SQL_Latin1_General_CP1_CS_AS
在MySQL中未知。已知的是latin1_general_cs
。
2
,2a
以及2y
平均为哈希算法和格式。我无法通过一些搜索找到一个简单的答案。
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
您可以在上面的链接上阅读更多内容,或者在GitHub上检查我的PHP实现。
如果您将PHP password_hash()
与PASSWORD_DEFAULT
算法配合使用来生成bcrypt哈希(我认为这是阅读此问题的大部分人),请记住,将来password_hash()
可能会使用其他算法作为默认算法,因此这可能影响哈希的长度(但不一定会更长)。
从手册页:
请注意,此常数旨在随着时间的推移而变化,因为新的和更强大的算法已添加到PHP。因此,使用此标识符的结果长度可能会随时间变化。因此, 建议将结果存储在可以扩展到超过60个字符的数据库列中(255个字符将是一个不错的选择)。
使用bcrypt,即使您有10亿用户(即您当前正在与Facebook竞争)来存储255字节的密码哈希,也只能存储约255 GB的数据-大约是较小的SSD硬盘的大小。存储密码散列成为应用程序的瓶颈的可能性极小。但是,由于某种原因,由于确实存在存储空间确实是个问题的机会,即使不是默认设置,您也可以PASSWORD_BCRYPT
强制password_hash()
使用bcrypt。只需确保随时了解bcrypt中发现的任何漏洞,并在每次发布新的PHP版本时查看发行说明。如果更改了默认算法,则最好回顾原因并做出明智的决定,以决定是否使用新算法。