你在哪里储存你的盐弦?
对数据库存储进行散列密码时,我总是使用适当的每个条目salt字符串。 为了我的需要,将盐存储在散列密码旁边的数据库中一直运行良好。
但是,有些人建议将salt与数据库分开存储。 他们的观点是,如果数据库受到攻击,攻击者仍然可以建立一个彩虹表并考虑特定的盐串,以便一次破解一个帐户。 如果此帐户具有管理员权限,那么他甚至可能不需要破解任何其他人。
从安全角度来看,将盐储存在不同的地方值得吗? 考虑在同一台计算机上使用服务器代码和数据库的Web应用程序。 如果salt存储在该机器上的平面文件中,那么很可能如果数据库受到损害,salt文件也会出现。
有没有推荐的解决方案?
彩虹表的重点在于它们是预先创建的,并且可以大规模地分发以节省其他人的计算时间 - 只需在飞行中生成彩虹表就可以直接生成彩虹表,因为它可以直接破解密码+盐组合(因为有效的办法是在生成彩虹表时预先运行用于强制散列的计算),因此通过了解盐可以“生成彩虹表”这一说法是虚假的。
将salt存储在单独的文件中并没有真正的意义,只要它们是基于每个用户的就可以了 - 盐的重点只不过是让一个彩虹表无法破坏数据库中的每个密码。
我会提供一个稍微不同的看法。
我总是将混合的盐与腌制密码混合存储。
例如,我将把盐的前半部分放在密码的盐渍散列之前,盐的后半部分放在密码的盐渍散列之后。 应用程序知道这个设计,所以可以获取这些数据,并获得salt和salted-password散列。
我的这种做法的基本原理是:
如果密码/散列数据受到攻击并落入攻击者手中,攻击者将无法知道盐是从查看数据的。 这样攻击者实际上不能实施强力攻击以获得与散列相匹配的密码,因为他不知道开始的散列并且无法知道哪部分数据是盐的一部分,或者部分腌制密码散列( 除非他确实知道你的应用程序的认证逻辑 )。
如果腌制密码哈希按原样存储,则可以执行暴力攻击来获取密码,该密码在腌制和散列时会生成与腌制密码哈希相同的数据。
但是,例如,即使唾沫密码哈希按原样存储,但预先添加了一个随机字节,只要攻击者不知道该第一个字节将被丢弃,这也会增加难度的攻击。 用于验证用户身份时,您的应用程序将知道丢弃数据的第一个字节。
这个结论..
1)不要以认真的形式存储认证应用程序使用的数据。
2)如果可能的话,保持您的验证逻辑的秘密,以增加安全性。
再往前走一步..
如果你不能保持你的应用程序的认证逻辑的秘密 - 很多人知道你的数据是如何存储在数据库中的。 假设你已经决定存储与盐一起混合的盐腌密码哈希,其中一些盐预先加了盐腌密码哈希,而其余的盐加上盐加上它。
当生成随机盐时,您还可以随机决定您将在盐渍密码哈希之前/之后存储的盐的比例。
例如,您生成一个512字节的随机盐。 您可以将salt添加到您的密码中,并获取您的腌制密码的SHA-512哈希值。 您还会生成一个随机整数200.然后,您会存储盐的前200个字节,然后是盐密码哈希,然后是盐的剩余部分。
在验证用户的密码输入时,应用程序将传递字符串,并假定数据的前1个字节是salt的前1个字节,后跟salt-hash。 此通行证将失败。 应用程序将继续使用数据的前2个字节作为盐的前2个字节,然后重复,直到使用前200个字节作为盐的前200个字节后找到肯定结果。 如果密码错误,应用程序将继续尝试所有排列,直到找不到任何排列。
这种方法的优点:
提高安全性 - 即使你的认证逻辑是已知的,确切的逻辑在编译时是未知的。 即使知道确切的逻辑,实际上也不可能执行暴力攻击。 盐的长度增加将进一步提高安全性。
这种方法的缺点:
由于确切的逻辑是在运行时推断的,所以这种方法非常耗费CPU资源。 盐的长度越长,这种方法的CPU密集度越高。
验证不正确的密码将涉及最高的CPU成本。 这可能会对合法请求产生反作用,但会增强对攻击者的安全性。
这种方法可以以各种方式实现,并且可以通过使用可变宽度的盐和/或腌制密码哈希来更加安全。
通常,它们被前置到散列并存储在相同的字段中。
不需要单独存储它们 - 关键是为每个密码使用一个随机盐,以便单个彩虹表不能用于整套密码哈希值。 使用随机盐,攻击者必须分别强制每个哈希值(或者为所有可能的盐计算一个彩虹表 - 大大增加工作量)。
如果你有一个更安全的存储位置,在那里存储哈希值是有意义的。
链接地址: http://www.djcxy.com/p/21549.html