我应该使用什么列类型/长度在数据库中存储Bcrypt哈希密码?

时间:2011-05-04 09:16:33

标签: mysql hash types storage bcrypt

我想在数据库中存储哈希密码(使用BCrypt)。什么是好的类型,哪个是正确的长度?密码是否与BCrypt长度相同?

修改

哈希示例:

$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu

在对某些密码进行哈希处理后,似乎BCrypt总是会生成60个字符的哈希值。

编辑2

很抱歉没有提及实施。我正在使用jBCrypt

4 个答案:

答案 0 :(得分:330)

bcrypt的模块化密码格式由

组成
  • $2$$2a$$2y$标识hashing algorithm and format
  • 表示费用参数的两位数值,后跟$
  • 53个字符长的base-64编码值(他们使用字母./0 - 9A - {{ 1}},Z - astandard Base 64 Encoding字母表不同)包括:
    • 22个字符的盐(实际上只有132个解码位的128位)
    • 加密输出的31个字符(实际上只有186个解码位的184位)

因此总长度分别为59或60字节。

当您使用2a格式时,您将需要60个字节。因此对于MySQL,我建议使用CHAR(60) BINARYor 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的解码如下:

  1. $<id>$可以用3位表示。
  2. <cost>$,04-31,可以用5位表示。将这些放在一起1个字节。
  3. 22个字符的盐是128位的(非标准)base-64表示。 Base-64解码产生16个字节。
  4. 31个字符的哈希摘要可以被base-64解码为23个字节。
  5. 将所有内容放在一起40个字节:1 + 16 + 23
  6. 您可以在上面的链接中阅读更多内容,或者在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个字符长