为哈希隐藏盐的必要性

时间:2008-10-17 18:49:39

标签: security encryption hash brute-force

在工作中,我们有两种相互竞争的盐理论。我工作的产品使用类似用户名或电话号码来加密哈希值。基本上每个用户都有不同的东西,但我们可以随时使用。另一个产品为每个用户随机生成一个salt,并在每次用户更改密码时更改。然后在数据库中加密盐。

我的问题是第二种方法是否真的有必要?从纯粹的理论角度来看,我可以理解它比第一种方法更安全,但从实用性的角度来看呢。现在要对用户进行身份验证,必须将salt解密并应用于登录信息。

在考虑之后,我只是没有从这种方法中看到真正的安全性收益。将盐从帐户更改为帐户,即使攻击者知道如何快速确定每个帐户的内容,仍然会使某人尝试强制执行散列算法变得非常困难。这是基于密码足够强的假设。 (显然,找到一组密码的正确哈希值,它们都是两位数,比找到8位密码的正确哈希值要容易得多)。我的逻辑是不正确的,还是我缺少的东西?

编辑:好的,这就是为什么我认为加密盐真的没什么问题。 (lemme知道我是否在正确的轨道上)。

对于以下说明,我们假设密码总是8个字符,盐是5,所有密码都是由小写字母组成的(这样可以简化数学运算)。

每个条目都有一个不同的盐意味着我不能使用相同的彩虹表(实际上,如果我有一个足够的大小,实际上我可以,但暂时忽略它)。根据我的理解,这是盐的真正关键,因为要破解每个帐户,我必须重新发明轮子,以便为每个人说话。现在,如果我知道如何将正确的盐应用于密码以生成哈希,我会这样做,因为盐实际上只是扩展了哈希短语的长度/复杂性。所以我会减少我需要生成的可能组合的数量以“知道”我有13 ^ 26到8 ^ 26的密码+盐,因为我知道盐是什么。现在这使它变得更容易,但仍然非常困难。

所以加密盐。如果我知道salt是加密的,我首先不会尝试解密(假设我知道它有足够的加密级别)。我会忽略它。不要试图弄清楚如何解密它,回到前面的例子,我只会生成一个更大的彩虹表,其中包含13 ^ 26的所有键。不知道盐肯定会减慢我的速度,但我认为它不会增加尝试首先破解盐加密的巨大任务。这就是为什么我不认为这是值得的。想法?

这是一个链接,描述了在暴力攻击下密码的持续时间: http://www.lockdown.co.uk/?pg=combi

10 个答案:

答案 0 :(得分:93)

不需要隐藏盐。

每个哈希都应使用不同的salt。实际上,通过从加密质量随机数生成器获取8个或更多字节很容易实现。

来自previous answer of mine

  

Salt有助于阻止预先计算的字典攻击。

     

假设攻击者有可能的密码列表。他可以散列每一个   并将其与受害者密码的哈希值进行比较,看看是否存在   火柴。如果列表很大,这可能需要很长时间。他没有   想要花很多时间在他的下一个目标上,所以他记录了结果   在“字典”中,哈希指向其对应的输入。如果   密码列表非常非常长,他可以使用像a这样的技术   彩虹表可以节省一些空间。

     

然而,假设他的下一个目标腌制了他们的密码。即使是   攻击者知道盐是什么,他的预计算表是   没有价值 - salt会更改每个密码产生的哈希值。他   必须重新哈希他列表中的所有密码,粘贴目标   盐输入。每种不同的盐需要不同的   字典,如果使用足够的盐,攻击者将没有空间   为他们所有人存储词典。交易空间以节省时间是不对的   更长的选择;攻击者必须回退散列每个密码   在他的每个目标列表中,他想要攻击。

     

因此,没有必要保密盐。确保   攻击者没有与之对应的预先计算的字典   特别是盐就足够了。


在考虑了这一点之后,我意识到愚弄自己认为可以隐藏盐是危险的。假设盐不能被隐藏,并且尽管如此设计系统是安全的,这样做要好得多。我提供了更详细的解释in another answer.

答案 1 :(得分:42)

这里的答案是问问自己你真正想要保护的是什么?如果有人可以访问您的数据库,那么他们可以访问加密的salt,并且他们也可以访问您的代码。他们可以解密加密盐吗?如果是这样,那么无论如何加密都是无用的。盐实际上是为了制作它所以如果它被打破,就不可能形成彩虹表来一次性破解你的整个密码数据库。从这个角度来看,只要每种盐都是独一无二的,就没有区别,每种密码都需要对你的盐或加密盐进行蛮力攻击。

答案 2 :(得分:3)

我对“盐”的理解是它使破解变得更加困难,但它并没有试图隐藏额外的数据。如果你试图通过使盐“秘密”来获得更多安全性,那么你真的只需要加密密钥中的更多位。

答案 3 :(得分:3)

第二种方法只是稍微安全一点。 Salts保护用户免受字典攻击和彩虹表攻击。它们使一个雄心勃勃的攻击者更难以破坏整个系统,但仍然容易受到针对系统中一个用户的攻击。如果您使用公开可用的信息,例如电话号码,并且攻击者会发现此,那么您已经为他们的攻击保存了一步。当然,如果攻击者获得您的整个数据库,盐和所有数据,问题就没有实际意义。

编辑:在重新阅读了这个答案和一些评论之后,我发现有些混淆可能是由于我只是比较这两个非常具体的问题中提出的案例:随机盐与非随机盐。如果攻击者获取了您的整个数据库,那么使用电话号码作为盐的问题没有实际意义,根本就没有使用盐的问题。

答案 4 :(得分:3)

隐藏的盐不再是盐。这是辣椒。它有它的用途。它与盐不同。

Pepper是添加到密码+ salt的密钥,它将哈希变为HMAC(基于哈希的消息验证代码)。有权访问哈希输出和盐的黑客理论上可以强制猜测将生成哈希的输入(因此在密码文本框中通过验证)。通过添加胡椒,您可以以加密随机方式增加问题空间,在没有严重硬件的情况下使问题变得难以处理。

有关胡椒的更多信息,请查看here

另见hmac

答案 5 :(得分:2)

这是一个简单的例子,说明为什么每个哈希值都有相同的盐

考虑下表

UserId  UserName,   Password
     1  Fred       Hash1 =  Sha(Salt1+Password1)    
     2  Ted        Hash2 =  Sha(Salt2+Password2)    

案例1当盐1与salt2相同 如果Hash2替换为Hash1,则用户2可以使用用户1密码登录

案例2当盐1不相同时盐2 如果Hash2被Hash1替换,则user2无法使用用户1密码登录。

答案 6 :(得分:2)

  

...类似于用户名或电话号码来加密哈希值。 ...

     

我的问题是第二种方法是否真的有必要?从纯粹的理论角度来看,我可以理解它比第一种方法更安全,但从实用的角度来看是什么?

从实际的角度来看,salt是一个实现细节。如果您更改了用户信息的收集或维护方式 - 并且用户名和电话号码有时会发生变化,使用您的确切示例 - 那么您可能已经损害了您的安全性。您是否希望这种面向外部的变更有更深层次的安全问题?

是否要求停止每个帐户都有电话号码的要求需要进行完整的安全审核,以确保您没有打开这些帐户以进行安全措施?

答案 7 :(得分:1)

有两种技术,目标不同:

  • “salt”用于使两个相同的密码以不同方式加密。这样,入侵者无法有效地对整个加密密码列表使用字典攻击。

  • 在散列消息之前添加(共享)“秘密”,以便入侵者无法创建自己的消息并接受它们。

答案 8 :(得分:0)

我倾向于隐藏盐。我使用10位盐,通过在密码开始之前将1到1024之间的随机数添加到密码的开头。当比较用户输入的密码与哈希时,我从1循环到1024并尝试盐的每个可能值,直到找到匹配。这不到1/10秒。我有这样的想法,从PHP password_hashpassword_verify这样做。在我的例子中,10比特的盐的“成本”是10。或者从另一个用户说,隐藏的“盐”被称为“胡椒”。盐未在数据库中加密。这是粗暴的强迫。它会使彩虹表必须将哈希值反转1000倍。我使用sha256是因为它很快,但仍然被认为是安全的。

答案 9 :(得分:-1)

实际上,这取决于您尝试保护数据的攻击类型。

每个密码的唯一salt的目的是防止对整个密码数据库进行字典攻击。

加密每个密码的唯一盐会使破解个人密码变得更加困难,是的,但是你必须权衡是否真的有很多好处。如果攻击者通过蛮力发现了这个字符串:

Marianne2ae85fb5d

哈希到存储在数据库中的哈希,是否真的很难弄清楚哪个部分是通道,哪个部分是盐?