所以,我很高兴使用per-user salt来哈希用户的密码。但是,accepted answer中有一条建议:
不要使用单独的色谱柱。
这对我没有意义。如果我只是将哈希和盐连接起来并将它们放在同一列中,那么它在语义上是等同于两个独立的列吗?在这种情况下,这只是默默无闻,不是吗?
使用单独的列来存储盐(只要是每个用户)就更容易了。为什么我不应该?
答案 0 :(得分:3)
如果你要为每个用户存储一个随机盐,那就无所谓了。将salt + hash存储在一列中,或者将salt和hash存储在两列中。 我个人会将它存储为单个列,因为你不可能只检索salt或只检索哈希值。此外,如果你更新salt,那么哈希也需要更新,当更新哈希时你不妨更新盐。从密码学的角度来看,任何一种存储方法都同样有效。
我认为该评论表明(虽然很差)是另一种解决方案是从另一条每用户数据中获取盐,衍生盐。
作为一个例子,取用户名并将其传递给PBKDF2的1000多次迭代(实际上选择一个独特且不寻常的迭代次数更好 - 比如2137)。这将要求攻击者不仅可以访问数据库而且还可以访问源代码来访问系统。
现在,如果攻击者可以完全访问密码表&您获得的源代码没有安全性,但是如果攻击只能访问数据库(有限的入侵),那么您已经停止了攻击,或者至少使攻击变得更加困难。
在派生盐实现中要考虑的另一个方面是,您的攻击者是否能够创建用户帐户(开放注册系统)。如果任何人(包括你的攻击者)可以创建一个帐户(比如说在stackoverflow上),派生的盐的价值就会降低。为什么?攻击者可以通过明文攻击(攻击者知道自己的密码和其他详细信息)对盐进行反向工程,从而只能访问数据库。
答案 1 :(得分:1)
我认为该主题中第一个答案的第二部分(关于“动态盐”的部分)给出了一个你想要的答案:生成一个随机的每用户盐并用散列密码存储它。这正是UNIX passwd(以及后来的影子)文件几十年来所做的事情。
该线程中有一些关于 salt 究竟是什么的混淆。一些回复采用了非常一般的定义,即“在执行单向散列之前将任何已知文本混合到密码中”。在执行单向散列之前混合已知文本和秘密文本有很多理由,显然在这种情况下对已知文本的处理将取决于算法。例如,请查看http://en.wikipedia.org/wiki/CRAM-MD5,这样可以避免让用户通过网络发送密码,方法是让服务器使用“salt”对其进行哈希处理。
答案 2 :(得分:1)
安全性答案是无关紧要的。
数据库的答案是salt和hash是不同的数量,因此理想情况下应将它们存储在不同的列中。如果您这样做,那么可以说数据库是规范化的。
然而,非规范化数据库以提高访问速度并不罕见 - 在同一列中连接散列和salt将是非规范化的一个例子。
保持盐和哈希分开的一个原因是您设想搜索其中一个或另一个。在我看来这不太可能是你想做的事情,所以继续把它们连接起来。