这个问题在这里已有答案:
我理解需要散列和腌制,但我不明白如何将盐存储在同一个(可能受到破坏的)数据库中,因为整个散列是安全的。例如,我正在学习的一本书通过随机生成一个整数并使用RNGCryptoServiceProvider创建一个byte []来指示为每个用户(好)创建一个唯一的哈希值。这一切都很好,但为了在登录时验证用户的密码,有必要从数据库(或其他一些文件)中读取该唯一的盐。这是一种储存盐的安全方式吗?
这是安全的,因为访问盐并不会使攻击过程更容易为攻击者撤消。给定密码,salt和哈希,您可以快速检查三元组是否正确。但是,您无法使用salt的知识来帮助您获取密码。
回想一下,首先需要盐的原因是避免相等的密码产生相等的哈希值。如果没有盐,攻击者就可以对“彩虹表”进行哈希处理,并检查编码字典的哈希值。
想象一下,你是一个坏人,你可以访问密码数据库。那里有很多信息,事情已经够糟糕了。对我们其他人来说唯一的好消息是这最终是死数据。你真正想要的是访问生活,运行系统,以及使该系统做任何你想做的事情的能力......特别是如果没有人知道你在。
这是诀窍。要获得访问权限,您无需实际发现真实密码:您只需找到一些导致相同哈希值的文本值。更糟糕的是,你不需要暴力破解结果。有一些有用的表格允许您快速查找将产生您需要的哈希值的文本。
那么,盐的目的是为这些预先计算的表添加皱纹。您可能有一个可以生成特定哈希的值,但是您预先计算的“彩虹表”不会考虑盐。 salt完全改变了哈希值。现在你又回到需要暴力破解个人密码的情况下,如果系统设计师使用了一个可能需要数年时间的良好加密算法。
这里的好处是盐即使你知道它的价值也会产生这种影响。只要拥有每用户盐,即使盐是公开的,也可以打破攻击者在密码数据库上使用彩虹表攻击的能力。
(但共享盐会让攻击者开始使用常用密码等运行破解解决方案,并开始在墙上扔东西......将哈希结果与所有用户进行比较,看看会出现什么情况)。
Salting增加了对受损数据库执行脱机攻击的难度。虽然拥有足够资源的攻击者最终会破解您的所有密码,但是腌制会使其在两个方面变得更难:
难度的增加允许更多时间来发现和减轻受损数据库的影响。
通过分离哈希和盐可以获得稍微更好的安全性,因为没有盐的攻击者必须强力盐。然而,在实践中,实现这种分离是困难和麻烦的,并且如果攻击者具有该访问级别,则攻击者很可能能够与密码一起获得盐。
Salting通过在预制表中查找来防止破解哈希。如果攻击者知道盐,它将不会帮助他们攻击这个攻击向量,因为他们仍然需要暴力破解密码。
每个用户使用不同的盐意味着他们必须花费所有资源来强制为单个用户强制匹配的哈希。因此,它不一定是“安全的”,而是破解整个数据库非常困难(不可能?),即使只有一个人需要花费大量精力才能破解。
您可以将每个记录的盐与全局盐组合在一起,这样即使您的数据库受到损害,它们仍然是一个缺乏可行的暴力的元素。
我会说两者兼顾 - 毕竟不能受伤......