这 3 种制造盐的方法的优点/缺点是什么?
$salt = md5($password);
$salt = sha1(md5($password));
$salt = generate_random_number();
计算哈希:
$hash = sha1($salt + $password);
这 3 种制造盐的方法的优点/缺点是什么?
$salt = md5($password);
$salt = sha1(md5($password));
$salt = generate_random_number();
计算哈希:
$hash = sha1($salt + $password);
要回答这个问题,重要的是要知道盐是什么。
盐是针对使用预先计算的表的攻击而设计的。例如彩虹表。彩虹表是一个巨大的表,所有可能的密码变化都达到一定长度。(使用巧妙的内存/时间权衡。)
如果攻击者只想破解一个密码,他们就没有优势。
上面的陈述是不正确的,如果
使用彩虹表的攻击者通常希望破解尽可能多的帐户。
除了第三种方法之外,您的所有方法都是不安全的。这是因为使用任何其他方法都允许攻击者为您的整个数据库计算彩虹表。
因为盐依赖于密码。也不要让它依赖于用户名,这仍然允许攻击者为 100 个最常见的用户名创建彩虹表。
前两种方法毫无价值。加盐的重点是相同的密码并不总是产生相同的加密/散列字符串。
如果您使“盐”仅依赖于密码,则相同的密码将始终产生相同的哈希值。所以基本上结果是一样的,如果你使用一个稍微不同的哈希函数而不加任何盐。
使用第三种方法,具有相同密码的两个用户通常会得到不同的盐,并且密码的哈希版本对于两个用户来说看起来不同。很难通过哈希来判断它们都具有相同的密码。
严格来说,您只有一种盐渍方法,您可以在其中计算哈希值。前三行是生成盐的不同方式。
所以有一种盐可以阻止预先计算的查找表发现密码。它应该是存储的固定值,最好是对被散列的纯文本唯一的。
最安全的方法是使用加密安全的随机数生成器来生成盐,然后将其与密码一起存储。
如果您创建了一个作为密码 MD5 的盐,那么它必须与散列和加盐的密码值一起存储,这意味着您有一个未加盐的散列,它容易受到预先计算的查找表的影响,除非您计划每次都计算它是一个小的性能损失。通过采用 MD5 散列的 SHA 散列,您可以减少纯文本值的可能性,因为 MD5 散列值的数量是有限的,因为它们是固定长度的。这意味着彩虹表查找可能比真正随机的盐有更大的成功机会。
所以请使用随机盐。
考虑彩虹表的一种有用方法是,可以为任何只有一个输入的单向(或“活板门”)函数构建它们。也就是说,如果您对所有密码使用相同的函数 F:hash = F(password)。F 可以是 MD5 或 SHA1 或其他。
现在让我们看看盐。您使用加盐函数 G,哈希 = G(盐,密码)。如果你的数据库中的所有密码都使用相同的盐,你可以构造一个函数 G,其中 G(password) = F("your salt", password),所以只有一个输入函数,因此你可以构建一个彩虹表.
如果盐取决于密码怎么办?说 salt = I(password),我们可以构建 J(password) = G(I(password), password),一个单一的输入函数,这样就可以构建彩虹表。
因此,每个密码都需要有自己的盐。这意味着,在攻击者破解您所有密码的时间里,他们只能破解一个。