Why does PHP crypt() prepend the salt to the hash?
我正在构建一个登录系统,在阅读了PHP手册之后,当您向
例子:
1 2 |
我的第一个想法是,这对那些试图逆转你的哈希值的人有帮助吗?
我在维基百科上查到了salt,上面写着:
For best security, the salt value is kept secret.
号
所以我不明白为什么crypt函数会返回所有用salt值预先填充的哈希值?
有什么原因吗?这应该是安全问题吗?
维基百科文章的作者将salt与搜索空间的概念混为一谈,暗示salt是一种阻止暴力攻击的方法。混淆这些想法并不能提高安全性;不能识别和描述这两个问题的人并不是可靠的指南。
salt的目的是阻止预先计算的查找表(如彩虹表)。salt防止攻击者将"space"转换为"time"。每一位salt都使表的存储需求翻倍;两字节salt的差异很大(65536倍),但8个字节需要不存在的"yottabyte"存储设备来查找表。
盐必须存放在某个地方。如果你有一个有效的方法来保持一个"秘密",为什么不使用它来存储密码并完全忘记散列呢?不需要;如果您想要真正的安全性,那么您需要设计系统以避免遭受暴力攻击,即使攻击者知道盐。文章认为盐可以保密的假设应该被视为是错误的。
通过加强密钥(应用哈希函数数千次)和密码选择规则(最小长度、数字、特殊字符),可以最好地防止暴力攻击。
假设salt不能被保密,这将鼓励更好的密钥增强和密码选择,从而导致更安全的系统。
我要说的是crypt并不像marc b说的那么糟糕,而且事实上,只要你不依赖于更弱的方案(如md5),它可能是最简单的哈希算法。
见:
如何使用bcrypt在PHP中散列密码?
http://uk.php.net/manual/en/function.crypt.php
http://www.openwall.com/phpass/
是的,盐应该是保密的,但是密码哈希也是保密的。他们在同一个地方同样保密是完全可以接受的。要对照哈希检查密码,您必须将salt与密码结合起来,然后对照哈希检查密码。因此,任何有权查看密码散列的用户或进程也应该有权查看salt,因为密码散列本身对于检查密码是不有用的(除非您打算强行执行salt)。
salt的目的是这样的,如果两个不同的用户拥有相同的密码,他们将散列到不同的东西上。这也意味着字典攻击要复杂得多,因为您不能简单地散列所有可能的密码,然后根据用户密码散列列表检查它们以查找多个用户的密码。相反,您必须尝试单个salt的密码才能找到一个用户的密码,或者尝试将所有可能的密码与多个salt组合在一起才能找到命中率。但是对salt本身的了解并不意味着您可以反转密码散列。它只是意味着你可以对密码哈希进行字典攻击。
如果你能找到一种方法让salt比hash值更安全,这当然不是一件坏事,但是当任何需要访问一个程序需要访问两者时,很难看出这是如何可行的。
php crypt从unix
盐值应该保密的说法容易被误解。为了获得最佳实践,您不应该以不发布密码散列的方式发布您的salt。给攻击者散列和盐可以让他们很容易地执行暴力攻击,而不会对您的系统产生可疑的流量。但是,即使攻击者可以看到salt和hash密码,系统也应该是安全的。
事实上,没有任何地方可以存储哈希,原则上,不能被黑客以与哈希密码完全相同的方式破坏。如果密码检查代码可以访问它,那么您必须假设泄露系统的人也可以访问它。
salt被附加到has,这样当您获得密码并想查看它是否与哈希匹配时,您就知道要使用哪个salt。这里的想法是对每个密码使用不同的salt,这样就不会有人预先计算哈希表。
您还可以在每个密码上附加第二个salt(对所有密码都一样),而不必告诉任何人它是什么。
crypt()函数已过时。在影子密码支持出现之前,它被用于散列旧式UNIX系统的密码。盐是为了增加强制密码的复杂性。但是,由于salt是由密码子系统随机生成的,因此必须将其存储在clear中,以便将来的任何密码操作都可以工作。如果SALT在加密之前已经嵌入到密码中,那么就没有实际的方法来验证密码——每次进行密码检查时,您都必须尝试所有可能的SALT——这是非常不切实际的。所以,salt是预先加密的密码,所以您可以再次将其提取出来以备将来使用。
1 2 3 4 5 6 7 | crypted password: xxabcdefghijklmn ^^- salt ^^^^^^^^^^^^^^-- crypted pw if ('xx' + crypt('xx' + password) == 'crypted string') then password is ok endif |
现在,crypt()的安全性相当于一个谷物盒解码器环。出于历史目的,低安全性"谁在乎它是否被破解成"存储。对于任何现代密码用法,最好使用更现代的散列,如sha1/sha256/md5。即使MD5现在被认为是坏的,sha1的边缘有裂缝,和(上次我检查)sha256仍然是安全的。