1

在存储密码时,据说 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 个字符,他也永远无法确定他是否已经到达纯文本版本,因为(如前所述)纯文本版本看起来像哈希。乍一看,他可能认为这是一个迭代版本,如果是这样,他可能会继续迭代,可能会无限期地迭代。

这种方法有什么问题吗,因为在哈希反转的情况下,保持盐的秘密可以提供额外的安全性,并且保持纯文本长度统一可以说增加了混淆层?

注意:这当然假设您的应用程序有多个失败的登录检测/预防。

4

3 回答 3

3

首先,除非你真的知道你在做什么,否则不要发明你自己的加密系统。

使用现有的(如PBKDF2bcrypt或 scrypt ),它们比简单的加盐散列具有优势,因为它们使用更多的 CPU 时间(全部三个)和/或内存(后两个),这使得并行化变得昂贵。

哈希中的盐只能防止彩虹表,而不是暴力攻击!

如果攻击者设法反转哈希,他将获得$pass.$salt(因此,密码)的知识。

salt 的目的是避免廉价地创建彩虹表,也就是说,攻击者不仅要计算每个可能密码的哈希值并将它们与您的数据库进行比较,还必须对每个不同的 salt 执行此操作。

保持盐的秘密具有使攻击更加昂贵的理论优势,因为攻击者还必须为每个可能的密码尝试所有可能的盐。

然而,在实践中,一旦他可以访问服务器 A,他可能就能够访问服务器 B。

如果某些东西看起来像哈希可能并不重要。一旦服务器受到威胁,攻击者可能会发现使用了哪些混淆技术。

附带说明:SHA-512产生 512 位输出,即 64 个 ASCII 字符。

于 2012-04-28T21:06:36.377 回答
1

这种方法的第一个问题是您正在实现自己的加密代码。这几乎总是一个坏主意。加密很难,而且很容易以微妙的方式搞砸,并且其他人已经投入了大量时间和精力来实现基于它们的加密原语和服务,因此您不必这样做。但是,为了争论,我们假设您确实需要这样做:-)。

第二件事是你截断了用户的输入——丢掉了宝贵的熵——根本没有任何好处。您已准备好生成多达 128 个字符的盐;为什么不总是这样做并将它们(连同密码)输入您的哈希?你通过截断得到什么?我看到的唯一答案是,据说原始密码“看起来像哈希,因为它是 128 个字符”,但这根本不是真的;您的加盐密码仍然以实际密码数据开头,这通常看起来与哈希非常不同。

第三件事——这可能只是我未能正确读懂你的想法——是不清楚你的这些盐是从哪里来的。您将它们描述为“随机的”,并说攻击者不会知道它们;但是您的身份验证系统如何获取它们?看起来它们是从密码中派生的,但在这种情况下,加盐加散列只是一个稍微复杂一点的散列函数,你并没有真正获得任何东西。

您显然拒绝(或者可能没有遇到)的一般原则是:始终设计密码系统,假设攻击者知道他们可能知道的一切,包括您的所有源代码。这是一个很好的原则,你不应该拒绝它。依靠一个小的“额外的混淆层”不会很好地为您服务;在最坏的情况下,它会更容易出现错误(通过使系统复杂化)并引起虚假的安全感。

于 2012-04-28T21:08:45.250 回答
0

盐不需要保密,它的唯一目的是保持所有哈希唯一

它还使得暴力破解哈希表“更慢”,因为您需要为每个哈希 + salt 组合每行尝试一次,而不是只为整个表尝试一个哈希(' select * from passwords where hash =' xxx'')

保持盐的秘密可以提供额外的安全性,并且保持纯文本长度统一可以说增加了混淆层?

您的“反向哈希”看起来像哈希这一事实并没有增加真正的额外安全性(它实际上只是默默无闻的安全性)。您的网络服务器将需要连接到服务器 A服务器 B(用于验证用户/密码组合),因此当该服务器受到威胁时,所有希望都将丢失。

您可能感兴趣的一篇文章是 Jeff Atwood 的这篇博文。(编辑:发布了错误的编码恐怖链接)

于 2012-04-28T21:05:04.757 回答