2

所以,我很喜欢使用每个用户的盐来散列我的用户密码。但是,在接受的答案中有一条建议:

不要为盐使用单独的列。

这对我来说没有意义。如果我只是将哈希和盐连接起来并将它们放在同一列中,那么这在语义上肯定等同于两个单独的列吗?在这种情况下,这只是默默无闻的安全,不是吗?

使用单独的列来存储盐更容易(只要它是每个用户的)。为什么我不应该?

4

3 回答 3

3

如果您要为每个用户随机存储一个盐,那并不重要。 将 salt+hash 存储在一列中,或者将 salt 和 hash 存储在两列中。 就我个人而言,我会将其存储为单列,因为您不太可能只检索盐或散列。 此外,如果您更新盐,那么哈希也需要更新,并且在更新哈希时,您不妨更新盐。从密码学的角度来看,任何一种存储方法都同样有效。

我认为该评论所表明的(尽管很糟糕)是另一种解决方案是从另一块每用户数据中派生盐,即派生的 salt

举个例子,取用户名并将其通过 PBKDF2 的 1000 多次迭代(实际上选择一个唯一且不寻常的迭代次数更好——比如 2137)。这将要求攻击者不仅可以访问数据库,还可以访问您的源代码以击败系统。

现在,如果攻击者可以完全访问密码表和源代码,那么您将无法获得安全性,但是如果攻击只能访问数据库(有限入侵),则您已经停止了攻击,或者至少使攻击变得更加困难。

在派生的 salt 实现中要考虑的另一个方面是您的攻击者是否能够创建一个用户帐户(开放注册系统)。如果任何人(包括你的攻击者)可以创建一个帐户(比如在 stackoverflow 上说),那么派生的盐的价值就会降低。为什么?攻击者可以对盐和盐源进行反向工程,只能通过明文攻击访问数据库(攻击者知道自己的密码和其他详细信息)。

于 2010-11-15T14:16:45.227 回答
1

安全答案是没关系。

数据库的答案是盐和哈希是不同的数量,因此理想情况下应该将它们存储在不同的列中。如果这样做,那么数据库可以说是规范化的。

但是,对数据库进行非规范化以提高访问速度的情况并不少见- 将哈希和盐连接在同一列中将是非规范化的一个示例。

将盐和哈希分开的一个原因是您设想搜索其中一个或其他。在我看来,这不太可能是您想要做的事情,所以继续将它们连接起来。

于 2010-11-20T14:54:47.600 回答
1

我认为该线程中第一个答案的第二部分(关于“动态盐”的部分)会给您一个您期望的答案:生成一个随机的每个用户的盐并将其与散列密码一起存储。这正是 UNIX passwd(以及后来的影子)文件几十年来所做的事情。

该线程中有一些关于盐到底是什么的混淆。一些回复采用非常笼统的定义,即“在执行单向哈希之前将任何已知文本混合到密码中”。在执行单向哈希之前混合已知文本和秘密文本有很多原因,显然在这种情况下对已知文本的处理将取决于算法。例如,请查看http://en.wikipedia.org/wiki/CRAM-MD5,它通过让用户使用服务器指定的“盐”对其进行哈希处理,完全避免了用户通过网络发送密码。

于 2010-10-31T01:43:52.823 回答