在存储密码时,据说 Salt 不需要保密,它的唯一目的是保持所有 Hash 的唯一性。也有人说限制密码长度不是一个好习惯,但考虑这个例子:
在散列之前,我们确保纯文本版本在内部始终为 128 个字符,方法是将用户输入修剪为最多 100 个字符,然后附加额外的字符作为我们的盐。
因此,如果用户输入 20 个字符,我们将附加 108 个随机字符作为盐。如果用户输入 100,我们追加 28,依此类推。关键是,纯文本版本的长度应该是 128 个字符。在代码中它可能看起来像这样:
$salt = generate_salt($pass); // length varies as explained above
$hash = hash('sha512', $pass.$salt);
这样,我们在散列之前的“纯文本”将始终为 128 个字符。
我们将 $hash 存储在服务器 A 上,并将 $salt 存储在服务器 B 上。
现在让我们假设攻击者获得了对哈希数据库(服务器 A)的访问权限并设法反转了哈希。对他来说看起来不错,但他看到的纯文本版本(或反向哈希)看起来仍然像哈希,因为它有 128 个字符。由于他不知道盐,他永远不会知道原始密码。
作为一个额外的挑战,由于 SHA512 产生 128 个字符,他也永远无法确定他是否已经到达纯文本版本,因为(如前所述)纯文本版本看起来像哈希。乍一看,他可能认为这是一个迭代版本,如果是这样,他可能会继续迭代,可能会无限期地迭代。
这种方法有什么问题吗,因为在哈希反转的情况下,保持盐的秘密可以提供额外的安全性,并且保持纯文本长度统一可以说增加了混淆层?
注意:这当然假设您的应用程序有多个失败的登录检测/预防。