在工作中,我们对盐有两种相互竞争的理论。我开发的产品使用用户名或电话号码之类的东西来对哈希进行加盐。本质上,每个用户的东西都是不同的,但我们很容易获得。另一个产品为每个用户随机生成一个盐,并在用户每次更改密码时更改。然后该盐在数据库中被加密。

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

经过思考后,我认为这种方法并没有带来真正的安全增益。即使攻击者知道如何快速确定每个帐户的盐值,将盐从一个帐户更改为另一个帐户仍然会使某人尝试暴力破解哈希算法变得极其困难。这是在密码足够强的假设下进行的。(显然,为一组全是两位数的密码找到正确的哈希值比找到 8 位数字的密码的正确哈希值要容易得多)。我的逻辑是否错误,或者我遗漏了什么?

编辑: 好吧,这就是为什么我认为加密盐确实没有意义的原因。(让我知道我是否走在正确的轨道上)。

对于以下解释,我们假设密码始终为 8 个字符,盐为 5 个字符,并且所有密码均由小写字母组成(这只是使数学更容易)。

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

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

以下链接描述了密码在暴力攻击下可以保存多长时间:http://www.lockdown.co.uk/?pg=combi

有帮助吗?

解决方案

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

其他提示

不需要隐藏盐。

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

来自我之前的回答

  

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

     

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

     

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

     

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


在考虑了这一点后,我意识到愚弄自己认为盐可以被隐藏是危险的。假设盐不能被隐藏,并且尽管如此设计系统是安全的,这样做要好得多。我在另一个地方提供更详细的说明答案。

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

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

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

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

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

有关辣椒的更多信息,请查看此处

另见 hmac

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

考虑下表

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密码登录。

  

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

     

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

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

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

有两种技术,具有不同的目标:

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

  • (共享)“秘密”是在对消息进行哈希处理之前添加的,这样入侵者就无法创建自己的消息并让它们被接受。

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

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

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

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

Marianne2ae85fb5d

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top