Security 我必须把我的盐和我的杂烩放在同一列吗?

Security 我必须把我的盐和我的杂烩放在同一列吗?,security,passwords,salt,Security,Passwords,Salt,所以,我很乐意使用a来散列我用户的密码。然而,在报告中有一条建议: 不要使用单独的盐柱 这对我来说毫无意义。如果我只是将hash和salt串在一起,并将它们放在同一列中,那么这在语义上肯定等同于两个单独的列?在这种情况下,这只是默默无闻的安全,不是吗 使用单独的列存储盐更容易(只要是每个用户)。为什么不呢?我认为该线程中第一个答案的第二部分(关于“动态盐”的部分)给出了一个与您期望的一样的答案:生成一个随机的、每个用户的盐,并使用哈希密码存储它。这正是UNIX passwd(以及后来的shado

所以,我很乐意使用a来散列我用户的密码。然而,在报告中有一条建议:

不要使用单独的盐柱

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


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

我认为该线程中第一个答案的第二部分(关于“动态盐”的部分)给出了一个与您期望的一样的答案:生成一个随机的、每个用户的盐,并使用哈希密码存储它。这正是UNIX passwd(以及后来的shadow)文件几十年来所做的


关于盐到底是什么,这条线索有些混乱。有些答复采用了非常笼统的定义,即“在执行单向散列之前,将任何已知文本混合到密码中”。在执行单向散列之前混合已知文本和机密文本有很多原因,显然,在这种情况下对已知文本的处理将取决于算法。例如,看看哪种方法可以避免用户通过网络发送密码,方法是让用户使用服务器指定的“salt”对其进行散列。

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

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

以username为例,通过1000多次PBKDF2迭代传递它(实际上选择一个独特的、不寻常的迭代次数更好,比如2137)。这将要求攻击者不仅可以访问数据库,还可以访问您的源代码,以击败系统

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


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

安全性答案是这无关紧要

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

然而,对数据库进行非规范化以提高访问速度并不少见——将哈希和salt连接在同一列中就是非规范化的一个例子


将盐和散列分开的一个原因是,您设想搜索其中的一个或另一个。在我看来,这不太可能是您想要做的事情,所以请继续将它们串联起来存储。

我同意您的观点-这没有任何意义……但它是否必须与散列存储在同一列中?我认为您引用的建议是,从某个预先存在的数据库列合成一种盐。因此,不要使用(因为您甚至不会创建)新列。如果您使用的是需要显式存储的随机盐,则不必将其与哈希本身放在同一列中。但是,如果没有salt,散列将毫无意义,因此如果将这两个列拆分,您将始终获取这两个列。