我不确定密码哈希是如何工作的(稍后将实现它),但现在需要创建数据库模式。
我正在考虑将密码限制为4-20个字符,但据我所知,加密哈希字符串将具有不同的长度。
那么,如何在数据库中存储这些密码呢?
我不确定密码哈希是如何工作的(稍后将实现它),但现在需要创建数据库模式。
我正在考虑将密码限制为4-20个字符,但据我所知,加密哈希字符串将具有不同的长度。
那么,如何在数据库中存储这些密码呢?
当前回答
作为一个固定长度的字符串(VARCHAR(n)或MySQL的称呼)。 哈希总是有一个固定的长度,例如12个字符(取决于您使用的哈希算法)。因此,20个字符的密码将被简化为12个字符的哈希,4个字符的密码也将生成12个字符的哈希。
其他回答
我一直在测试寻找加密字符串的最大字符串长度,并将其设置为VARCHAR类型的字符长度。根据您将拥有多少条记录,它确实有助于数据库大小。
这取决于你使用的哈希算法。如果我没记错的话,密码的长度和散列的长度没有什么关系。查找您正在使用的哈希算法的规格,运行一些测试,并截断上面的部分。
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不建议使用这些简单的哈希函数来安全地存储密码。
较小的哈希算法有它们的用途(比如应用程序内部,而不是用于交换),但众所周知它们是容易被破解的。
为了向前兼容,您应该使用TEXT(存储无限数量的字符)。随着时间的推移,哈希算法(需要)变得更加强大,因此随着时间的推移,这个数据库字段将需要支持更多的字符。此外,根据您的迁移策略,您可能需要在同一个字段中存储新的和旧的散列,因此不建议将长度固定为一种类型的散列。