【问题标题】:What is the purpose of salt?盐的目的是什么?
【发布时间】:2011-06-30 09:02:24
【问题描述】:

在 Linux 系统中,密码使用 MD5 散列存储。为什么使用“盐”可以更好地保护系统?特别是要明确以下两点

  1. 据说盐储存在 带有哈希的明文,然后如何 它可以防止攻击者当 攻击者知道盐值。 (攻击者可以是系统 可以检查的管理员本人 /etc/shadow
  2. 如果盐是随机生成的 每次,系统怎么能 比较哈希以验证 用户?

比如用户A有用户salt s1,生成h1; h1 = md5(password.s1);。 下一次,它使用 salt s2,系统必须生成不同的哈希,h2 = md5(password.s2)。既然h1不等于h2,那么系统如何认证用户呢?

【问题讨论】:

标签: security md5 salt


【解决方案1】:

如您所知,MD5 是一个散列,因此如果您给它一个输入,例如“PASSWORD”,您会得到一个独特的(希望 - 但是现在 MD5 有冲突)输出,例如“3DE2AF...”。

现在,如您所知,直接反转它是相当困难的,直到有人想到......等等,我为什么不预先生成所有可能的哈希值组合,直到我可以反转哈希。这称为rainbow table

盐的目的是将任意随机数据添加到被散列的字符串中,这样您就可以增加散列的输入长度。这意味着希望仅将密码输入反转为哈希的通用彩虹表将不起作用。当然,彩虹表只是反向查找,您可以简单地生成一个彩虹表来补偿所有可能的密码+盐输出。这就是长度增加的地方。由于反向哈希的性质,为非常长的哈希输入生成反向的磁盘空间很快变得不可行。 6-8 个字符的字母数字彩虹表已经是几千兆字节了;增加长度和字符类,你开始以 10GB 的倍数说话。

当然,如果您使用 'PASSWORD' 进行盐渍化并且您对 'PASSWORD' 进行哈希处理,那么您正在对 'PASSWORDPASSWORD' 进行哈希处理,这并没有那么安全,所以盐的选择也很重要。理想情况下,您应该对每个散列字符串使用随机盐,但当然,您需要知道它是什么。一种常见的技术是从用户名或这种情况下特有的一些其他属性派生盐。添加任意数据本身并没有用。拥有用户确定的盐数据现在增加了额外的复杂性,这意味着需要针对每个用户进行专门搜索的彩虹表。你越让这件事变得困难,就越需要更多的计算能力。这就是战斗的所在。

但是,有一些现代技术。我不是专家,所以我不能告诉你这些有多安全,但它们值得一提。这个概念是慢散列。基本上,通过复合散列函数,您可以花费一些时间来计算每个散列。因此,每个用户检查密码的能力现在为您希望检查的每个密码添加了恒定的时间。如果你是暴力破解,那就是坏消息(tm)。同样,如果系统设计良好,如果没有捷径(这可能等同于弱点),那么为慢速哈希函数生成彩虹表也需要一段时间。

编辑这里有更多细节。第一个例子见crypt()@CodeInChaos 引用了 PBKDF2,它构成了 PKCS#5 的一部分。较新的开发是scrypt

正如我所说,我不是密码分析专家。关于后一个例子,我对它的适用性没有特别的专业知识,我只是向你展示事情的发展方向。

编辑 2 澄清了我写的盐 - 我想我之前围绕磁盘空间的关键问题跳舞。

【讨论】:

  • 虽然我个人喜欢 scrypt 的想法,但我还没有看到太多关于它的分析。所以我宁愿选择一种较旧的标准化 KDF。 scrypt 的优势只有在面对使用定制硬件或 FPGA 的攻击者时才会发挥作用。
  • @CodeInChaos 嗯。那是我最近看过/谈论的那个,所以我想到了那个。但你是对的,它还没有机会被彻底审查。
  • 我想知道salt是否以明文形式存储,攻击者可以根据具体的salt构建一个彩虹表。
  • @user49 盐不是。它被添加到你散列的内容中。但是,是的,如果您知道或知道该字符串是如何构造的,则可以取消盐对特定情况的好处。但这就是问题 - 这将视具体情况而定。密码学/哈希等不是绝对安全的;这样做的目的是让攻击者尽可能地困难。
  • 通常系统只是在密码后面加上盐,然后做哈希,对吗?或者如果我是系统管理员,这个机制并不难理解。
【解决方案2】:

当您加密数据时,它仍然可能受到bruce-force attacksrainbow attacks 的攻击。在加盐中,在加密数据的末尾添加一些额外的位。所以攻击者无法正确获取原始数据。

【讨论】:

    【解决方案3】:

    您可以通过暴力破解简单的哈希算法。

    如果您使用常用词作为密码,某些预构建表(如rainbow ones)可能包含它们。这就是大多数算法多次调用哈希函数的原因:

    md5(md5(md5(password)));
    

    使用 salt 为生成的密码提供了更多的随机性,从而降低了密码的可猜测性。它包括在过程中添加一段随机字符串

    md5(md5(md5(password+string)+string)+string);
    

    【讨论】:

    • 很好的答案,但我还有一个问题! md5(md5(md5(password))); 允许在编程语言中使用吗?多个散列密码能否暴露彩虹和蛮力?
    • 为什么不应该呢? md5 接受一个字符串作为参数并返回一个字符串。您可以多次调用它。反转每个哈希对攻击者来说比哈希器花费更多的时间和资源。
    • 通常你不会自己写md5(md5(...)) 之类的东西,而是使用已知且经过审查的密钥派生函数。例如基于 HMAC 的 PBKDF2。并且重复调用哈希函数对彩虹表没有多大帮助。许多迭代用于减慢蛮力,盐用于防止彩虹表。
    • md5 是不可逆的,但是您可以很容易地找到哈希到相同值的字符串,这使得用于在不使用盐的情况下混淆您的密码的算法非常糟糕。盐不会给它随机性,而是使它成为这样,如果您确实使用了与没有盐的散列时的散列值匹配的密码,则它不会与添加的盐匹配散列。这增加了安全性,因为您必须先知道散列值和盐值,然后才能从彩虹表中找出要使用的值。
    • 我应该说它“不会给它随机性除非你使用随机盐”没有随机盐,这是一个简单的转换。
    【解决方案4】:

    一个原因可能是,如果两个人在不知情的情况下使用相同的密码,他们将生成相同的 MD5。其中一个人可以看到 /etc/shadow 并猜测其他人的密码。

    现在每个密码都添加了盐,即使是相同的密码也会产生不同的哈希值。

    【讨论】:

    • 如果密码太简单以至于它意外地生成了相同的哈希值,那么它也是微不足道的暴力破解。
    • 也就是说如果shadow文件使用md5,更不用说那些也是salted的。即使他们不是,除非操作系统严重破坏了权限,如果一个人可以读取影子,那么你就有更大的问题了:)
    • 如果您对每个密码使用不同的盐,则情况如此,但如果您在所有密码之间共享盐,则不会。如果您使用相同的盐,它们将散列到相同的值。但是,即使您使用不同的密码,它们也会散列到相同的值。在这种情况下,使用盐应该强制它们散列到不同的值。在任何情况下,除 root 之外的任何人都不能读取 /etc/shadow,如果他们有 root 访问权限,那么无论如何你都被搞砸了。
    • @CodeInChaos:每个字符串的哈希值都是相同的,无论是 3 个字符还是 30 长,实际上是允许攻击者对其进行暴力破解...
    猜你喜欢
    • 2010-12-25
    • 1970-01-01
    • 2010-09-12
    • 2018-03-23
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 2010-09-19
    • 2011-01-11
    相关资源
    最近更新 更多