我不确定密码哈希是如何工作的(稍后将实现它),但现在需要创建数据库模式。

我正在考虑将密码限制为4-20个字符,但据我所知,加密哈希字符串将具有不同的长度。

那么,如何在数据库中存储这些密码呢?


当前回答

为了向前兼容,您应该使用TEXT(存储无限数量的字符)。随着时间的推移,哈希算法(需要)变得更加强大,因此随着时间的推移,这个数据库字段将需要支持更多的字符。此外,根据您的迁移策略,您可能需要在同一个字段中存储新的和旧的散列,因此不建议将长度固定为一种类型的散列。

其他回答

这取决于你使用的哈希算法。如果我没记错的话,密码的长度和散列的长度没有什么关系。查找您正在使用的哈希算法的规格,运行一些测试,并截断上面的部分。

for md5 vARCHAR(32)是合适的。对于那些使用AES的人来说,最好使用varbinary。

你可能会发现维基百科上这篇关于腌制的文章很有价值。这个想法是添加一组数据来随机化你的哈希值;如果有人未经授权访问密码散列,这将保护您的密码免受字典攻击。

更新:简单地使用哈希函数存储密码是不够强大的。你应该阅读Gilles在这个帖子上的回答,以获得更详细的解释。

对于密码,使用密钥强化哈希算法,如Bcrypt或Argon2i。例如,在PHP中,使用password_hash()函数,该函数默认使用Bcrypt。

$hash = password_hash("rasmuslerdorf", PASSWORD_DEFAULT);

结果是一个60个字符的字符串,类似于下面的内容(但是数字会有所不同,因为它生成了一个唯一的salt)。

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

使用SQL数据类型CHAR(60)来存储Bcrypt散列的这种编码。注意,这个函数没有编码为十六进制数字字符串,所以我们不能轻易地将其解十六进制存储为二进制。

其他哈希函数仍然有用途,但不用于存储密码,所以我将保留下面的原始答案,写于2008年。


这取决于你使用的哈希算法。不管输入是什么,哈希总是产生相同长度的结果。典型的做法是将二进制哈希结果表示为文本,即一系列十六进制数字。或者您可以使用UNHEX()函数将十六进制数字字符串减半。

MD5 generates a 128-bit hash value. You can use CHAR(32) or BINARY(16) SHA-1 generates a 160-bit hash value. You can use CHAR(40) or BINARY(20) SHA-224 generates a 224-bit hash value. You can use CHAR(56) or BINARY(28) SHA-256 generates a 256-bit hash value. You can use CHAR(64) or BINARY(32) SHA-384 generates a 384-bit hash value. You can use CHAR(96) or BINARY(48) SHA-512 generates a 512-bit hash value. You can use CHAR(128) or BINARY(64) BCrypt generates an implementation-dependent 448-bit hash value. You might need CHAR(56), CHAR(60), CHAR(76), BINARY(56) or BINARY(60)

截至2015年,NIST建议在任何需要互操作性的哈希函数应用中使用SHA-256或更高版本。但是NIST不建议使用这些简单的哈希函数来安全地存储密码。

较小的哈希算法有它们的用途(比如应用程序内部,而不是用于交换),但众所周知它们是容易被破解的。

哈希是一个比特序列(128位、160位、256位等,取决于算法)。如果MySQL允许,你的列应该是二进制类型的,而不是文本/字符类型的(SQL Server数据类型是二进制(n)或varbinary(n))。你还应该给散列加盐。盐可以是文本或二进制,您需要一个相应的列。