我刚刚查看了Django中密码散列的实现并注意到that it prepends the salt,因此散列的创建方式就像sha1(salt + password)
一样。
在我看来,盐有两个目的
防止彩虹表查找
好吧,预先添加/添加盐对彩虹表并没有什么影响。
强化蛮力/字典攻击
这就是我的问题所在。如果有人想从被盗的密码数据库中攻击一个密码,他需要尝试很多密码(例如字典词或[A-Za] z0-9]排列)。
假设我的密码是“abcdef”,盐是“盐”,攻击者会尝试所有[a-z] {6}个密码。
使用前置盐,必须计算hash("salt")
,存储哈希算法的状态,然后从该点继续进行每个排列。也就是说,遍历所有排列将需要26 ^ 6个复制哈希算法的状态结构操作和26 ^ 6 hash(permutation of [a-z]{6})
个操作。由于复制哈希算法的状态非常快,所以无论多长时间,盐都不会增加任何复杂性。
但是,使用附加的salt,攻击者必须为每个排列计算hash(permutation of [a-z]{6} + salt)
,从而导致26 ^ 10个哈希操作。很明显,附加盐会增加复杂程度,具体取决于盐的长度。
我不相信这是出于历史原因,因为Django相当新颖。那么预先添加盐的含义是什么?
答案 0 :(得分:10)
请勿使用Key derivation function之类的标准PBKDF2。永远不要滚动你自己的加密。弄错了太容易了。 PBKDF2使用多次迭代来防止暴力,这比简单的排序要大得多。
除非salt的长度对应于底层块cypher的块长度,否则在处理salt之后预先计算散列函数内部状态的技巧可能不容易实现。 / p>
答案 1 :(得分:1)
如果使用salt,攻击者可以为盐制作哈希状态数据库(假设盐的长度足以进行哈希步骤),然后运行字典攻击。
但是如果追加盐,攻击者可以为密码字典创建这样的数据库,另外只计算salt的哈希值。鉴于盐通常比密码短(如4个字符盐和8个字符密码),攻击速度会更快。
答案 2 :(得分:0)
当然,你正在提出一个有效的观点;但是,实际上,如果你想增加计算哈希的时间,只需使用更长的哈希值。例如,SHA256而不是SHA1。