什么是 SaltedHash 足够好的盐?

信息安全 密码 哈希
2021-08-13 04:27:16

由于我使用自己的盐对所有密码进行哈希处理,因此盐是真正随机的,或者增量计数器或 guid 是否足够好?此外,使用较大的盐与较小的盐有什么好处?

编辑: 既然已经确定哈希不应该太小:盐的足够大小是多少?guid(16字节)可以吗?

3个回答

盐的唯一目的是唯一:没有两个散列密码应使用相同的盐值。这是为了防止成本分摊,例如预先计算的哈希表。

唯一性应该是全球性的。例如,假设您使用一个简单的计数器作为盐。相应地,值“1”将用作第一个创建的帐户的盐,大概是服务器管理员的帐户。这对于该服务器的所有已安装实例都是如此。这使得使用“1”作为盐预先计算潜在散列密码的大表(例如彩虹表)是值得的,因为该表可用于攻击使用该软件的所有服务器上的管理员密码。在这里打坐的词是“值得”。

由于服务器范围的唯一性是不够的,因此计数器是不够的;用户名也不是很好的盐(用户名在给定的服务器上是唯一的,但是那里有很多“Bob”、“Joe”和“DarkLord42”)。UUID (GUID) 应该可以解决问题您还可以使用强大的统一伪随机生成器(/dev/urandom, CryptGenRandom(), java.security.SecureRandom... 取决于您使用的平台)并从中获取足够的随机字节,以便重用盐值的风险足够小;16 个字节就足够了。使用随机性是“稳健的方式”,因为它以足够高的概率产生唯一性,而不必依赖世界范围的惯例。

感谢 Hendrik 对这个问题的评论,我找到了一个与此相关的线程。以下是我的发现:

  • 使用增量计数器作为盐仍然会使彩虹表的使用变得更加困难。
  • 越大通常越好,并且首选随机性以避免重复使用。

如果每个人(或至少几个人)都使用相同的盐集(即递增数字或短盐),则可以为所有重复的盐创建彩虹表,从而使这些加盐哈希不太安全。

因此,盐最好在系统之间也应该是唯一的,而不仅仅是在我的系统中,以避免创建一组彩虹表并用于破坏多个系统。(一张表用于 salt=1,一张用于 salt=2,一张用于 salt=3,依此类推。)

盐不需要是随机的或秘密的。它只是为了阻止使用例如彩虹表的攻击,或者使这种攻击更慢。如果我没记错的话,用他/她的用户名加盐用户密码应该是安全的。