我不知道密码哈希如何运作(将在后面实现它),但是现在需要创建数据库模式。
我想限制密码4-20个字符,但作为我加密哈希串后才明白会有不同的长度。
那么,如何在数据库中存储这些密码?
我不知道密码哈希如何运作(将在后面实现它),但是现在需要创建数据库模式。
我想限制密码4-20个字符,但作为我加密哈希串后才明白会有不同的长度。
那么,如何在数据库中存储这些密码?
更新:您只需通过哈希函数不是存储密码足够强大。 你应该阅读从吉尔斯的答案在此线程的更详细的解释。
对于密码,使用密钥加强哈希算法像Bcrypt或Argon2i。 例如,在PHP,使用password_hash()函数 ,它默认使用Bcrypt。
$hash = password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
其结果是类似于以下(但数字会有所不同,因为它产生一个唯一的盐)的60字符串。
$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
使用SQL数据类型CHAR(60)
用于存储Bcrypt散列的这种编码。 注意:此功能不编码为十六进制数字组成的字符串,所以我们不能那样容易UNHEX它以二进制存储。
其他散列函数还是有用途,但不存储密码,所以我会保持低于原来的答案,写于2008年。
这取决于你使用的哈希算法。 总是散列产生相同长度的结果是,不管输入的。 这是典型的代表文本二进制散列结果,作为一系列的十六进制数字。 或者你也可以使用UNHEX()
函数减少一半的十六进制数字的字符串。
截至2015年,NIST 建议使用SHA-256或更高为需要互操作性的散列函数的应用程序。 但NIST不建议使用这些简单的散列函数,用于存储密码的安全。
较小的散列算法有其用途(如内部到应用程序,而不是交换),但它们是已知的裂化 。
实际上,你可以使用CHAR(哈希长度)来定义你的MySQL的数据类型,因为每个散列算法将永远评估出来的相同数量的字符。 例如,SHA1总是返回一个40个字符的十六进制数。
您可能会发现在这个腌制维基百科的文章值得的 。 我们的想法是将数据添加到您的随机哈希值的设置位; 如果有人获取到密码哈希未经授权的访问,这将保护你的密码,从字典攻击。
作为固定长度的字符串(VARCHAR(n)或然而MySQL调用它)。 散列始终例如12个字符(取决于所使用的散列算法)的固定长度。 因此,一个20字符的密码将减少到一个12字符的散列,以及一个4炭密码也将产生一个12字符的散列。
Argon2赢得了2015年的密码哈希竞争。 Scrypt , bcrypt和PBKDF2是被认为不太现在首选旧的算法,但仍不能从根本上完善的,所以如果你的平台不支持Argon2的是,它是确定使用另一种算法了。
不要直接在数据库中存储的密码。 不要加密,或者:否则,如果您的网站被攻破,攻击者获得了解密密钥,因此可以获得所有的密码。 密码必须散列 。
密码哈希具有从哈希表散列或密码散列不同的特性。 从来没有使用普通的加密散列,例如MD5,SHA-256或在密码SHA-512。 密码散列算法采用的是盐 ,它是唯一的(不用于其他任何用户或任何其他人的数据库)。 盐是必要的,这样攻击者不能只是预先计算常见密码的哈希值:用食盐,他们必须重新启动每个帐户计算。 密码散列算法在本质上是慢 -慢,你能负担得起。 缓慢伤害攻击者有很多比你更因为攻击者尝试许多不同的密码。 欲了解更多信息,请参阅如何安全散列密码 。
密码散列编码四种信息:
许多库包括方便地封装该信息作为一个字符串的一对功能:即需要该算法指示器,硬度指示符和密码,生成随机盐并返回完整散列串; ,而另一种密码和完整的哈希值的字符串作为输入,并返回一个布尔值,指示密码是否正确。 有没有统一的标准,但一个共同的编码
$algorithm$parameters$salt$output
其中algorithm
是一个数字或编码算法的选择一个短字母数字串, parameters
是可打印字符串,以及salt
和output
都以Base64而不终止编码=
。
16个字节是足够的盐和输出。 (参见例如用于Argon2建议 。)编码为Base64,这是每21个字符。 另外两个部分依赖于算法和参数,但20-40个字符是典型的。 这是一个总的约82个ASCII字符 ( CHAR(82)
并且无需对Unicode),对此,如果你认为这将是以后难以放大字段中应该增加一定的安全边际。
如果在二进制格式编码的散列,就可以得到它归结为1个字节的算法,1-4个字节的硬度(如果硬编码的一些参数),并且每个16个字节的盐和输出,共计37个字节。 说是40个字节 ( BINARY(40)
至少有一对夫妇的备用字节。 请注意,这些都是8位字节,不可打印的字符,特别是该领域可以包括空字节。
需要注意的是哈希的长度是完全无关的密码的长度。
这真的取决于你使用的哈希算法。 密码的长度没有什么用的哈希长度,如果我没有记错。 查找规格上正在使用的哈希算法,运行几个测试,并截断只是上面。
哈希值是比特序列(128位,160位,256位等,根据不同的算法)。 您的列应该是二进制类型,而不是文本/字符类型,如果MySQL允许它(SQL Server数据类型是binary(n)
或varbinary(n)
你也应该盐哈希值。 盐可以是文本或二进制,你将需要一个相应的列。
您应该使用TEXT
向前兼容的缘故(存储无限数量的字符)。 散列算法(需要)随着时间的推移更强,因此这个数据库字段将需要随着时间的推移,以支持更多的字符。 不建议另外根据您的迁移策略,你可能需要存储新老哈希在同一领域,所以固定长度一个散列类型。
我一直测试,以找到一个加密的字符串的最大字符串长度,并设置为VARCHAR类型的字符长度。 根据你要多少记录有,它可以真正帮助数据库大小。
为MD5 VARCHAR(32)是合适的。 对于使用AES更好地使用这些VARBINARY。