【发布时间】:2013-01-04 05:23:27
【问题描述】:
我一直在研究更好的程序来保护 php 应用程序中的密码。形式上我会使用类似的东西(只是一个例子,不要开枪!):
$salt = md5(rand() . md5(rand() . '$%E$%SDRT');
$password = md5('supersecret', $salt);
然后我会为数据库中的每个密码生成不同的盐,以防止使用彩虹表。
虽然看起来大多数(明智的)人正在转向 bcrypt(),但在网上寻找。关于它是如何工作的,它为什么工作等等有很多问题,但我不明白它是如何更安全的?请注意,我可能对这里的理解感到困惑
据我了解,当您使用 crypt($pass, $salt) 时,盐实际上可以作为 crypt 的指示符,告诉它使用什么算法。根据 php 手册,您使用“$2a$07”,它告诉 crypt 在 log2 回合中使用河豚。然后它会吐出一个包含盐作为前缀的字符串。
手册中的示例:
Blowfish: $2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi
似乎所有密码的盐值都保持不变。我不明白这是如何安全的。黑客似乎更容易找到盐(甚至不需要从盐柱中拉出),并且在开始时有一个信标指示使用的回合和算法。这怎么能更安全?我知道更多的轮次会对硬件造成更高的损失,使其可扩展并增加破解密码所需的时间(由于成本),但它也准确地表明了它是如何完成的。
另外,我喜欢自己编写尽可能多的应用程序,以便更好地了解其工作原理,并且如果可能的话,我更愿意远离 openwall。我不喜欢依赖其他人的代码并反过来吸收他们的漏洞。我宁愿对自己的漏洞负责并自己修复它们。
还有一件事。如果增加轮数,这是否意味着当前密码散列将与数据库中的散列不匹配?您是否必须重置所有用户的密码,或者您是否在他们下次登录时慢慢地将他们移向新的轮数?
正如我所说,这只是我的理解,所以可能只是我的理解混淆了。我不认为这是您可以“尝试并失败”的情况之一,因为如果您失败了,您可能会看到的不仅仅是一个损坏的应用程序......
我一直在阅读的内容:
What is the correct format for a blowfish salt using PHP's crypt?
PHP Manual - Crypt
Openwall phpass
How to create and store password hashes with Blowfish in PHP
How do you use bcrypt for hashing passwords in PHP?
【问题讨论】:
-
如果增加轮数,哈希值会改变。你可以标记谁没有被“重新散列”;如果他们通过了身份验证,则获取他们输入的密码,重新散列,存储它,并将其标记为已更新。
-
but it also indicates exactly how it was done.无论您使用什么,攻击者都将始终知道它是如何完成的。编辑:您更喜欢自己编写代码而不是使用经过测试的解决方案的意义是(至少在这种情况下)是愚蠢的,并且比任何纯文本密码存储对您的应用程序造成的伤害更大。 -
这是我问这个问题的主要原因之一