有很多关于盐和最佳实践的问题,但其中大多数只是回答了关于它们的非常具体的问题。我有几个问题可以相互补充。
假设数据库遭到破坏,每个用户的盐阻止使用通用彩虹表来破解密码。必须为每个拥有唯一盐的用户生成一个单独的彩虹表才能获得他们的密码。这将是一个耗时的过程,而这正是使盐有效的原因。这对抵御字典或暴力攻击没有很大帮助。
这导致了一些问题:
- 虽然盐不应该是security through obscurity将盐放在单独的 table 上不是更安全吗? 这样即使“用户”表受到损害,盐也不会受到损害。
- 使用第二个硬编码应用程序范围的 salt 会增加大量的安全性吗? 这样即使数据库被破坏,实际的应用程序也必须被破坏,否则盐和散列将完全无用。
- 盐的最佳长度是多少?显然越长越好,但是随着用户数量的增加,数据库大小确实成为一个问题,那么有效盐的最小长度是多少?
- 是否真的需要使用第 3 方来源来获取“真正的随机盐”(random.org、random.irb.hr)? 我知道使用基于服务器时间的 salt 在某种程度上是“可猜测的”,但是采用 sha1 随机字符串的随机子字符串似乎是一种有效的 salt 方法。
提前谢谢你。
最佳答案
如果黑客可以访问您的数据库系统,那么您就是 fsckd。您的系统必须能够访问这两个表才能运行,因此从已经破坏系统的黑客那里“隐藏”其中一个的可能性几乎为零。在我看来,不值得额外的复杂性。
为每个密码添加(另外)一个“nonce”到 salt 并没有多大帮助,但也没有什么坏处。
如果操作正确,即使是 16 位盐通常也足以使密码破解变得不可行。我可能会使用 64 或 128 位,为什么不呢?
您应该使用“良好”的随机源,但它不需要是完美的。如果随机值以某种方式对攻击者可见,那么他们可能能够找到一种方法来预测下一个随机值,但他们必须在创建密码时这样做,并且只会让他们获得一个密码。
简而言之,您需要针对每个用户的 salt 和良好的散列函数。 MD5 很糟糕,SHA-1 不再“好”。您应该使用像 bcrypt 这样的系统来迫使攻击者在每个散列上花费相当多的一秒钟。每次密码检查 0.1 秒对您来说可能没什么大不了,但它对任何类型的暴力破解都是毁灭性的。
任何实现密码安全方案的人都需要阅读:
关于database - 关于哈希盐的综合信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1745114/