代码之家  ›  专栏  ›  技术社区  ›  Catfish

关于盐渍密码的另一个问题

  •  1
  • Catfish  · 技术社区  · 15 年前

    我知道有很多关于盐渍密码的博客、文章和问题,但有一件事我找不到答案:

    如果生成这样的密码哈希:

    $salt = randomString
    $password = $_POST['password'] 
    hashedPassword = sha1($password.$salt)
    

    我有一张这样的桌子:

    Users
    user_id | hashedPassword | salt
    

    为什么攻击者很难找出这个密码?难道他们就不能用彩虹表,或者蛮力找出盐,然后把盐加到字典攻击中的每个单词上吗?

    5 回复  |  直到 12 年前
        1
  •  5
  •   Michael Borgwardt    15 年前

    他们不能用彩虹桌吗? 或者用蛮力去找出盐,

    那怎么办?但不管怎样这都不是问题- 假设攻击者 知道 盐。它的目的不是保密的,这就是为什么你要把它存储在哈希旁边。

    然后在每个单词后面加上盐 在字典攻击中?

    当然,他们可以这样做,但他们必须为特定的用户这样做。它们不能将工作分散到数据库中的所有用户身上,也不能使用预先计算的hash->密码映射表。

    只有这才是盐的关键所在。

        2
  •  3
  •   ircmaxell    15 年前

    他们能做到。其功能是,它们因此需要为每个密码生成一个新的彩虹表(或者迭代每个密码的每个字典条目)。

    因此,单个密码的总计算时间与普通salt的计算时间相同。但是多个密码的总计算时间呈指数增长…

    哦,有两种盐通常被认为是很好的做法。一个存储在数据库中,每个密码哈希都是唯一的,另一个存储在文件系统中,整个站点都是唯一的。这样一来,如果数据库遭到破坏,就没有什么大问题了,因为它们只使用了1/2的盐。当然,如果文件系统被破坏了,他们可以得到全部,但是如果文件系统被破坏了,他们可以安装密码嗅探器和其他的恶意程序…

    我希望这有助于…

        3
  •  3
  •   Community Mohan Dere    8 年前

    重要的是不要让单一密码更强大。这是为了防止攻击者在攻击多个密码时扩大攻击范围。有了盐,攻击者就不能再利用他的努力来攻击另一个密码;他必须重新编写他的字典。

    彩虹表并不是什么神奇的东西;它们只是预先计算好的表的一个特例,这类似于一个简单的字典攻击,具有略微不同的时空模式。建立彩虹表意味着或多或少要通过完整的字典。如果攻击者可以使用预计算表攻击多个密码,则预计算表对他是一种收益。如果密码是用盐腌制的,那么不管彩虹与否,预先计算好的表格都不会给他带来任何好处。

    也就是说,单个密码通常很弱,而且可以被强制执行,因为普通的密码适合普通用户的大脑,因此也不可能非常复杂。为了降低这种风险,应该使用重复的或迭代的散列。盐在这里没有帮助(但也没有伤害)。见 this answer 有关详细信息。

        4
  •  2
  •   Justin Ethier    15 年前

    嗯,首先,他们不能使用预先计算的彩虹表来发现碰撞——攻击者必须使用salt生成自己的彩虹表。另外,假设每个用户都有不同的盐,那么彩虹表只对单个用户有效——这使得他们的工作变得更加困难。

        5
  •  1
  •   David Schwartz    12 年前

    让我们用一个简单的例子:我们有两个数据库, 阿尔法 贝塔 :

    阿尔法 只需散列密码并存储结果:

    row: {
        passwordHash = Hash(password)
    }
    

    贝塔 为每个用户创建一个随机值,并将其用作哈希函数输入的一部分:

    row: {
        salt = RandomString(),
        passwordHash = Hash(password + salt)
    }
    

    现在假设您的对手事先知道您的一些用户正在使用密码: "password"

    在中查找所有用户 阿尔法 其密码是 “密码” ,您只需要计算 “密码” 曾经。以下是来自SQL的示例:

    DECLARE @Hash INT; SET @Hash = Hash("password");
    SELECT UserID FROM Users WHERE passwordHash = @Hash
    

    因为它只涉及整数相等,所以它的效率和查询的效率差不多。即使 阿尔法 如果有成千上万的用户,它会很快返回。

    事实上 贝塔 的散列在每个密码散列中都包含一个行特定的随机值,您不能为其编写一个同样有效的查询。最接近的方法是重新计算每行的哈希函数 salt :

    SELECT u.UserID FROM Users u WHERE u.passwordHash = Hash("password" + u.salt)
    

    事实上, 已知的 密码太贵了,应该说明执行暴力攻击的代价有多高,即使这种攻击是由常用密码的字典引导的,或者是尝试像人类那样混合单词和数字来创建密码的算法。


    你已经知道了 是防御“彩虹表”攻击的措施,所以你的问题是…怎样?

    “彩虹表”已经成为任何攻击的华丽词汇,它可以提前计算常见和潜在密码的散列值,并将它们存储在一个有效的查找表中。一旦构建了该表(可能需要几个小时),就可以遍历每个用户,查看他们的密码哈希是否在查找表中。如果是的话,您可能已经猜到了该用户的密码。

    内部用户 阿尔法 确实很容易受到这种攻击。 阿尔法 对于相同的密码将具有相同的哈希,因此可以使用哈希表或彩虹表来反转哈希。但是 贝塔 巧妙地通过使哈希函数的结果对用户来说是唯一的,从而避开了此漏洞

    希望有一天这能帮助一些读者!