我一直在研究更好的程序来保护 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。我不喜欢依赖其他人的代码并反过来吸收他们的漏洞。我宁愿对自己的漏洞负责并自己修复它们。
还有一件事。如果增加轮数,这是否意味着当前密码散列将与数据库中的散列不匹配?您是否必须重置所有用户的密码,或者您是否在他们下次登录时慢慢将他们移向新的轮数?
正如我所说,这只是我的理解,所以可能只是我的理解混淆了。我不认为这是您可以“尝试并失败”的情况之一,因为如果您失败了,您可能会看到的不仅仅是一个损坏的应用程序......
我一直在阅读的内容:
使用 PHP 的 crypt 的河豚盐的正确格式是什么?
PHP 手册 - Crypt
Openwall phpass
如何在 PHP 中使用 Blowfish 创建和存储密码哈希
如何在 PHP 中使用 bcrypt 对密码进行哈希处理?