你在哪里储存盐弦?

对数据库存储进行哈希密码处理时,我总是使用正确的per-entry saltstring。 为了我的需要,将散列密码旁边的salt存储在散列密码旁边一直工作正常。

但是,有些人build议将salt与数据库分开存放。 他们的观点是,如果数据库被攻破,攻击者仍然可以build立一个彩虹表,考虑一个特定的盐串,以便一次破解一个帐户。 如果这个帐号拥有pipe理员权限,那么他甚至不需要破解其他任何人。

从安全的angular度来看,将盐储存在不同的地方是值得的吗? 考虑在同一台机器上使用服务器代码和数据库的Web应用程序。 如果盐被存储在该机器上的平面文件中,那么很可能如果数据库受到损害,那么盐文件也是如此。

有没有推荐的解决scheme?

彩虹表的重点在于,它们是预先创build的,并且可以大量分发以节省其他人的计算时间 – 只需要在飞行中生成彩虹表,就可以直接破解密码+盐的组合(因为有效的办法是在生成彩虹表时预先运行计算器来强制哈希),因此,通过知道盐有人可以“生成彩虹表”的说法是虚假的。

把salt存储在一个单独的文件中是没有意义的,只要它是基于每个用户的就可以了 – 盐的要点就是使一个彩虹表不能破坏DB中的每个密码。

我将提供一个稍微不同的意见。

我总是把盐混合在一起的盐密码哈希。

例如,我将把盐的前半部分放在密码的盐渍散列之前,盐的后半部分放在密码的盐渍散列之后。 应用程序知道这个devise,所以可以获取这个数据,并获得盐和盐密码哈希。

我的理由是:

如果密码/哈希数据被泄露并落入攻击者手中,攻击者将不知道从查看数据中得知盐是什么。 这样一来,攻击者实际上不可能执行暴力攻击来获得与散列相匹配的密码,因为他不知道开始的散列,也无法知道哪部分数据是盐的一部分,或者部分腌制密码散列( 除非他确实知道你的应用程序的authentication逻辑 )。

如果腌制密码哈希按原样存储,则可以执行暴力破解攻击以获得当腌制和散列时产生与腌制密码哈希相同的数据的密码。

但是,例如,即使唾沫密码哈希按原样存储,但是预先填充了一个随机字节,只要攻击者不知道该第一个字节将被丢弃,这也会增加难度的攻击。 用于validation用户的应用程序将知道丢弃数据的第一个字节。

这个结论

1)不要以确切的forms存储authentication应用程序使用的数据。

2)如果可能的话,保持您的validation逻辑的秘密,以增加安全性。

再往前走一步

如果你不能保持你的应用程序的身份validation逻辑的秘密 – 很多人知道你的数据存储在数据库中。 假设你已经决定存储与盐一起混合的盐渍密码哈希,盐的一些盐预先加了盐渍密码哈希,盐的其余部分加上盐。

当生成随机盐时,您还可以随机决定在盐腌密码散列之前/之后将存储的盐的比例。

例如,您生成一个512字节的随机盐。 你把salt加到你的密码上,并获得你的密码的SHA-512散列。 您还会生成一个随机整数200.然后,您将存储盐的前200个字节,然后是盐密码哈希,接下来是盐的剩余部分。

在validation用户的密码input时,应用程序将传递string,并假定数据的前1个字节是盐的前1个字节,接着是盐味散列。 这个通行证将失败。 应用程序将继续使用数据的前2个字节作为盐的前2个字节,然后重复,直到使用前200个字节作为盐的前200个字节后find肯定的结果。 如果密码错误,应用程序将继续尝试所有排列,直到找不到任何排列。

这种方法的优点:

更高的安全性 – 即使你的authentication逻辑是已知的,确切的逻辑在编译时是未知的。 即使知道确切的逻辑,实际上也不可能执行暴力攻击。 盐的长度增加将进一步提高安全性。

这种方法的缺点:

由于确切的逻辑是在运行时推断的,所以这种方法非常耗费CPU资源。 盐的长度越长,这种方法的CPU密集度越高。

validation不正确的密码将涉及最高的CPU成本。 这可能会对合法请求产生反作用,但会增加对攻击者的安全性。

这种方法可以以各种方式实现,并且可以通过使用可变宽度的盐和/或腌制密码哈希来更加安全。

通常,它们被前置到散列并存储在相同的字段中。

没有必要单独存储它们 – 关键是为每个密码使用一个随机盐,这样一个彩虹表就不能用于你的整套密码哈希值。 随机盐,攻击者必须分别强制每个散列(或计算所有可能的盐的彩虹表 – 远远更多的工作)。

如果你有一个更安全的存储位置,在那里存储哈希将是有意义的。

基于开发ASP.NET MVC 4 Web应用程序的书籍William Penberthy:

  1. 获得访问存储在一个单独的数据库中的盐需要黑客入侵两个不同的数据库,以获得盐和盐腌密码。 将它们存储在与密码相同的表中,或者甚至是同一个数据库的另一个表中,意味着当黑客获得对数据库的访问时,它们将有权访问salt和密码哈希。 由于安全包括黑客进入系统的过程太昂贵或耗时,值得一提的黑客必须获得的访问量增加一倍应该使系统更安全。
  2. 易于使用是将盐保留在哈希密码所在的同一数据库中的主要原因。 您不必确保两个数据库始终可用,并始终保持同步。 如果每个用户都有一个随机盐,那么获得盐的好处是最小的,因为虽然它可能使得个人密码的发现更容易,但是破解整个系统的密码所需的力量将是高的。 在这个层面的讨论中,这是真正的期望是:保护密码。 如果黑客已经获得了数据库的副本,那么您的应用程序数据已经被盗用。 此时,由于共享密码的潜力,问题在于缓解用户的风险。
  3. 维护两个单独的链接数据库的要求非常广泛。 当然,它增加了安全感,但是它提供的唯一好处是它保护了一个密码,一个单一的数据元素。 如果数据库中的每个字段都被单独encryption,并且使用相同的盐,则将数据与数据分开存储将更有意义,因为系统的基本安全性得到了提高。