对于哈希密码字段,应使用哪种数据类型和长度?

11 浏览
0 Comments

对于哈希密码字段,应使用哪种数据类型和长度?

我不确定密码散列的工作原理(稍后将进行实现),但现在需要创建数据库架构。

我考虑将密码限制在4-20个字符,但据我了解,在加密后,散列字符串的长度将不同。

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

0
0 Comments

问题的原因是SHA-1算法不适合用于哈希密码字段。SHA-1是一种哈希算法,用于将输入数据转换为固定长度的字符串。然而,由于SHA-1算法的弱点,如碰撞攻击和彩虹表攻击,使得使用SHA-1哈希密码不再安全。

为了解决这个问题,我们需要选择一个更安全的哈希算法来替代SHA-1。常见的选择包括SHA-256、SHA-384和SHA-512等更强大的算法。这些算法产生的哈希值长度更长,使得碰撞攻击和彩虹表攻击变得更加困难。

在MySQL数据库中,可以使用CHAR数据类型来定义哈希密码字段的数据类型。由于每个哈希算法的计算结果都会得出相同长度的字符,因此可以使用CHAR加上哈希值的长度来定义数据类型。例如,SHA-1算法总是返回一个包含40个字符的十六进制数。

使用正确的数据类型和更安全的哈希算法可以提高密码的安全性,降低密码泄露和破解的风险。

0
0 Comments

在存储密码字段时,应该使用什么数据类型和长度的问题是因为密码需要进行哈希处理,以增加安全性。以下是解决这个问题的方法:

1. 始终使用密码哈希算法,如Argon2、scrypt、bcrypt或PBKDF2。Argon2在2015年的密码哈希比赛中获胜。Scrypt、bcrypt和PBKDF2是较旧的算法,虽然现在被认为不太受欢迎,但仍然基本可靠。如果你的平台还不支持Argon2,现在使用其他算法也是可以的。

2. 绝对不要直接在数据库中存储密码,也不要对其进行加密。否则,如果你的网站遭到入侵,攻击者将获得解密密钥,从而可以获取所有密码。密码必须进行哈希处理。

3. 密码哈希与哈希表哈希或加密哈希有不同的属性。绝不要对密码使用普通的加密哈希算法,如MD5、SHA-256或SHA-512。密码哈希算法使用一个唯一的盐值,这个盐值不用于其他用户或任何其他数据库中。盐值的作用是防止攻击者预先计算常见密码的哈希值。有了盐值,攻击者必须为每个账户重新计算哈希值。密码哈希算法是相对较慢的,因为它要比较多个不同的密码。详情请参考“How to securely hash passwords”。

4. 密码哈希包含四个部分的信息:

- 使用的算法指示器。这是必要的,以便实现密码算法的灵活性,因为密码算法的推荐方法随着时间的推移而变化。你需要能够过渡到新的算法。

- 难度或硬度指示器。这个值越高,计算哈希值所需要的计算量越大。这应该是一个常量或全局配置值,在密码更改函数中,但随着计算机速度的增加,这个值应该随时间增加,所以你需要记住每个账户的值。一些算法只有一个数值,其他算法有更多的参数(例如,分别调整CPU使用率和内存使用率)。

- 盐值。由于盐值必须是全局唯一的,所以它必须存储在每个账户中。盐值应在每次密码更改时随机生成。

- 哈希值本身,即哈希算法的数学计算的输出。

5. 许多库包括一对函数,以将这些信息方便地打包为一个字符串:一个函数接受算法指示器、难度指示器和密码作为输入,生成一个随机盐值,并返回完整的哈希字符串;另一个函数接受密码和完整的哈希字符串作为输入,并返回一个布尔值,指示密码是否正确。虽然没有通用的标准,但一种常见的编码方式是:

$$$$

其中是一个编码算法选择的数字或短的字母数字字符串,是一个可打印的字符串,以Base64编码,没有终止符=

6. 盐值和哈希值的长度取决于算法和参数,但通常情况下,盐值和哈希值的长度是20到40个字符。以Base64编码,每个字符占21个字符。另外两个部分的长度是固定的82个ASCII字符,所以总共大约需要82个字符的长度。如果你认为以后可能会难以扩大字段,可以添加一些安全裕度。

7. 如果将哈希值编码为二进制格式,可以将其压缩为算法的1个字节、难度的1-4个字节(如果一些参数被硬编码),以及盐值和哈希值的每个16个字节,总共37个字节。为了保险起见,可以设置为40个字节,至少还有几个空闲字节。注意,这些是8位字节,而不是可打印字符,特别是该字段可以包含空字节。

8. 注意,哈希值的长度与密码的长度没有任何关系。

0
0 Comments

在存储哈希密码字段时,应该使用什么数据类型以及长度的问题,出现的原因是因为简单地使用哈希函数来存储密码不够强大。为了更详细地解释这个问题,我们可以阅读Gilles在这个线程上的回答。对于密码,应该使用一个像Bcrypt或Argon2i这样的密钥加强哈希算法。例如,在PHP中,可以使用password_hash()函数,默认使用Bcrypt。

哈希密码字段的数据类型可以使用CHAR(60)来存储Bcrypt哈希的编码。需要注意的是,这个函数并不是将其编码为十六进制数字的字符串,所以不能像将其转换为二进制那样容易。

其他哈希函数仍然有用途,但不适用于存储密码,因此我将保留原始的2008年的回答。

根据哈希算法的不同,哈希值的长度也不同。MD5生成一个128位的哈希值,SHA-1生成一个160位的哈希值,SHA-224生成一个224位的哈希值,SHA-256生成一个256位的哈希值,SHA-384生成一个384位的哈希值,SHA-512生成一个512位的哈希值,BCrypt生成一个与实现相关的448位哈希值。

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

为了增加安全性,可以通过在每个密码前缀添加一个唯一的值(例如用户名)来进行盐值。这样可以防止使用彩虹表攻击方法的密码破解尝试。

需要注意的是,不能将用户名作为盐值,应该为每个用户生成一个随机的盐值。

随机生成的盐值是否存储在同一行中?

是的,没有理由不将其存储在同一行中。即使攻击者获得了对数据库的访问权限,他们也必须基于该盐值构造彩虹表。这和猜测密码的工作量一样大。

如果我要黑数据库密码,我肯定会将某个未知字段作为盐值。我对彩虹表有一些了解,但可能还不足以认为有人能够编写一个绕过/盐值脚本,并将密码表的每一列作为盐值,然后运行彩虹表。因此,如果不加盐值,一张表的彩虹表就足够了,如果您使用未知盐值的正确方式,那么这样做的努力对于黑客来说是否太大,以至于不用考虑行*列来处理所有用户的情况?

请记住,为给定的盐生成彩虹表需要很多工作和空间。即使您知道盐值,通过穷举搜索猜测密码可能更容易。如果您存储盐值在同一张表中(或任何其他具有相同访问权限的位置),没有理由不使用用户名作为盐值,因为它对每个用户来说都是唯一的。然而,任何已知的盐值都会使哈希在密码学上比没有已知盐值的哈希更弱。只有当盐值是未知的时候,盐值才有价值。

此外,已知位哈希函数并不更容易被破解。可能会有更少的可能性,所以暴力破解更加可行,但是虽然有办法模拟MD5或SHA1哈希,但它们的算法仍然没有被证明有缺陷。简单的strlen()检查使得复制密码哈希变得不可行。我并不是说MD5或SH1是一个完全安全的解决方案,只是有点迂腐。

我不明白已知盐值和未知盐值之间的区别。如果您正在实现一个网站,盐值需要为登录页面/脚本/服务知道,以便对密码进行测试。因此,您这些主张“未知”盐值的人,是不是假设登录过程的代码对攻击者是未知的?否则,攻击者不会始终知道盐值,无论它是随机的,唯一的,与哈希密码一起存储还是分开存储?

我认为没有人建议公开使用盐值。服务器端代码需要查询相应用户的盐值,然后使用它对用户的输入进行哈希运算,然后将结果与以前存储在数据库中的密码哈希值进行比较。在任何时候,盐值都不会离开服务器或变成公开的。

拥有盐值比没有盐值要好,但这仍然不足够,而且你忘记在给出MD5等大小时考虑到盐值。MD5、SHA-256等“普通”哈希算法不适用于密码(不,NIST并不推荐将它们用于密码)。您必须存储盐值,并且必须使用诸如PBKDF2、bcrypt、scrypt或Argon2等密码哈希算法。

在2008年编写这个答案时,已经越来越流行的最佳做法是使用像Bcrypt或PBKDF2这样的自我盐化哈希算法。详见stackoverflow.com/questions/6832445/…。

最佳做法是根本不使用盐值。如果有一个更简单的解决方案,而且它与现有的解决方案一样好,却没有被使用,那么Sisko正在做他的工作,Garak正在制定保证的备用计划。然后,晚安。

为什么在括号内的长度在BINARY和CHAR之间不同?我知道BINARY是直接除以8,但CHAR的数字是如何计算的?谢谢。

将8位信息编码为二进制字节需要每8位信息1字节,这很简单。但是,将8位信息显示为十六进制符号(0-9和A-F)需要每8位2个字符。十六进制将对最高8位值显示为FF,这需要两个字符。而在二进制中,您可以将相同的8位值存储在一个二进制字节中。

这很令人困惑。我一直认为sizeof(char) = 1字节 = 8位,所以BINARY(8) = CHAR(1),但这是一个字符串文字字符计数。

是的,如果将哈希编码为人类可读的十六进制数字,就必须使用字符串。每个字符中只能使用16个不同的符号,但一个字符仍然需要1字节来存储。因此,每个字节中只有4位信息,而将8位数据编码需要两个字符。

0