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

本文翻译自:What column type/length should I use for storing a Bcrypt hashed password in a Database?

I want to store a hashed password (using BCrypt) in a database. 我想在数据库中存储散列密码(使用BCrypt)。 What would be a good type for this, and which would be the correct length? 什么是好的类型,哪个是正确的长度? Are passwords hashed with BCrypt always of same length? 密码是否与BCrypt长度相同?

EDIT 编辑

Example hash: 示例哈希:

$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu

After hashing some passwords, it seems that BCrypt always generates 60 character hashes. 在对一些密码进行哈希处理之后,似乎BCrypt总是生成60个字符的哈希值。

EDIT 2 编辑2

Sorry for not mentioning the implementation. 很抱歉没有提及实施。 I am using jBCrypt . 我正在使用jBCrypt


#1楼

参考:https://stackoom.com/question/oFXz/我应该使用什么列类型-长度在数据库中存储Bcrypt哈希密码


#2楼

A Bcrypt hash can be stored in a BINARY(40) column. Bcrypt哈希可以存储在BINARY(40)列中。

BINARY(60) , as the other answers suggest, is the easiest and most natural choice, but if you want to maximize storage efficiency, you can save 20 bytes by losslessly deconstructing the hash. 正如其他答案所暗示的那样, BINARY(60)是最简单和最自然的选择,但是如果你想最大化存储效率,你可以通过无损解构散列来节省20个字节。 I've documented this more thoroughly on GitHub: https://github.com/ademarre/binary-mcf 我在GitHub上更详细地记录了这一点: https//github.com/ademarre/binary-mcf

Bcrypt hashes follow a structure referred to as modular crypt format (MCF). Bcrypt哈希遵循称为模块化密码格式(MCF)的结构。 Binary MCF (BMCF) decodes these textual hash representations to a more compact binary structure. 二进制 MCF(BMCF)将这些文本哈希表示解码为更紧凑的二进制结构。 In the case of Bcrypt, the resulting binary hash is 40 bytes. 在Bcrypt的情况下,得到的二进制散列是40个字节。

Gumbo did a nice job of explaining the four components of a Bcrypt MCF hash: Gumbo很好地解释了Bcrypt MCF哈希的四个组成部分:

$<id>$<cost>$<salt><digest>

Decoding to BMCF goes like this: 对BMCF的解码如下:

  1. $<id>$ can be represented in 3 bits. $<id>$可以用3位表示。
  2. <cost>$ , 04-31, can be represented in 5 bits. <cost>$ ,04-31,可以用5位表示。 Put these together for 1 byte. 将这些放在一起1个字节。
  3. The 22-character salt is a (non-standard) base-64 representation of 128 bits. 22个字符的盐是128位的(非标准)base-64表示。 Base-64 decoding yields 16 bytes. Base-64解码产生16个字节。
  4. The 31-character hash digest can be base-64 decoded to 23 bytes. 31个字符的散列摘要可以基本64位解码为23个字节。
  5. Put it all together for 40 bytes: 1 + 16 + 23 将它们放在一起40个字节: 1 + 16 + 23

You can read more at the link above, or examine my PHP implementation , also on GitHub. 您可以在上面的链接中阅读更多内容,或者在GitHub上查看我的PHP实现


#3楼

If you are using PHP's password_hash() with the PASSWORD_DEFAULT algorithm to generate the bcrypt hash (which I would assume is a large percentage of people reading this question) be sure to keep in mind that in the future password_hash() might use a different algorithm as the default and this could therefore affect the length of the hash (but it may not necessarily be longer). 如果您使用PHP的password_hash()PASSWORD_DEFAULT算法生成bcrypt哈希(我认为这是很大一部分人阅读此问题)请务必记住,将来password_hash()可能会使用不同的算法因为默认值,这可能会影响哈希的长度(但它可能不一定更长)。

From the manual page: 从手册页:

Note that this constant is designed to change over time as new and stronger algorithms are added to PHP. 请注意,此常量旨在随着时间的推移而变化,因为新的和更强大的算法被添加到PHP中。 For that reason, the length of the result from using this identifier can change over time. 因此,使用此标识符的结果长度可能会随时间而变化。 Therefore, it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice). 因此, 建议将结果存储在数据库列中,该列可以扩展到超过60个字符 (255个字符将是一个不错的选择)。

Using bcrypt, even if you have 1 billion users (ie you're currently competing with facebook) to store 255 byte password hashes it would only ~255 GB of data - about the size of a smallish SSD hard drive. 使用bcrypt,即使你有10亿用户(即你目前正在与facebook竞争)存储255字节的密码哈希,它只会有~255 GB的数据 - 大约相当于一个小型SSD硬盘的大小。 It is extremely unlikely that storing the password hash is going to be the bottleneck in your application. 存储密码哈希极不可能成为应用程序的瓶颈。 However in the off chance that storage space really is an issue for some reason, you can use PASSWORD_BCRYPT to force password_hash() to use bcrypt, even if that's not the default. 然而,在关闭的机会,存储空间真的出于某种原因的问题,您可以使用PASSWORD_BCRYPT强制password_hash()使用bcrypt,即使这不是默认的。 Just be sure to stay informed about any vulnerabilities found in bcrypt and review the release notes every time a new PHP version is released. 请务必随时了解bcrypt中发现的任何漏洞,并在每次发布新的PHP版本时查看发行说明。 If the default algorithm is ever changed it would be good to review why and make an informed decision whether to use the new algorithm or not. 如果更改默认算法,最好查看原因并做出是否使用新算法的明智决定。


#4楼

I don't think that there are any neat tricks you can do storing this as you can do for example with an MD5 hash. 我不认为你可以做的任何巧妙的技巧存储,例如你可以用MD5哈希。

I think your best bet is to store it as a CHAR(60) as it is always 60 chars long 我认为你最好的选择是将它存储为CHAR(60)因为它总是60个字符长


#5楼

The modular crypt format for bcrypt consists of bcrypt的模块化密码格式包括

  • $2$ , $2a$ or $2y$ identifying the hashing algorithm and format $2$$2a$$2y$标识哈希算法和格式
  • a two digit value denoting the cost parameter, followed by $ 表示成本参数的两位数值,后跟$
  • a 53 characters long base-64-encoded value (they use the alphabet . , / , 09 , AZ , az that is different to the standard Base 64 Encoding alphabet) consisting of: 53个字符长的base-64编码值(它们使用字母表./0 - 9A - Za - z标准Base 64编码字母表不同)包括:
    • 22 characters of salt (effectively only 128 bits of the 132 decoded bits) 盐的22个字符(实际上只有132个解码位的128位)
    • 31 characters of encrypted output (effectively only 184 bits of the 186 decoded bits) 加密输出的31个字符(实际上只有186个解码位的184位)

Thus the total length is 59 or 60 bytes respectively. 因此总长度分别为59或60字节。

As you use the 2a format, you'll need 60 bytes. 当您使用2a格式时,您将需要60个字节。 And thus for MySQL I'll recommend to use the CHAR(60) BINARY or BINARY(60) (see The _bin and binary Collations for information about the difference). 因此,对于MySQL,我建议使用CHAR(60) BINARYBINARY(60) (有关差异的信息,请参阅_bin二进制排序规则 )。

CHAR is not binary safe and equality does not depend solely on the byte value but on the actual collation; CHAR不是二进制安全的,并且相等不仅仅依赖于字节值,而是依赖于实际的整理; in the worst case A is treated as equal to a . 在最坏的情况下, A被视为等于a See The _bin and binary Collations for more information. 有关更多信息,请参阅_binbinary排序规则

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值