3

我一直在研究更好的程序来保护 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 对密码进行哈希处理?

4

2 回答 2

0

据我了解,您的问题是“为什么使用可变盐进行散列更安全?”。

只有一件事:它总是暴力破解,如果盐是恒定的,那么只需一个暴力破解循环就可以“破解”所有密码。(如果哈希等于数据库中的一 - 我们知道用户密码)。

对于简单的 md5() 和 sha1() 哈希函数,还可以将生成的暴力密码哈希存储在数据库中(以备将来使用)。这种方法允许黑客在几秒钟内确定几乎所有的密码。

于 2013-01-21T14:16:38.673 回答
0

对于所有密码,盐似乎也保持不变。我不明白这是如何安全的。

您需要稍微不同地使用 bcrypt。不要将真实密码作为密码参数传递。您可以在字符串的中间添加、附加或放入一些生成的“盐”字符串。然后将带有输出哈希的盐存储到您的存储中。

当用户输入他/她的密码然后获取盐时,对盐和 bcrypt() 再次执行相同的操作,并将结果与​​您存储的哈希值进行比较。

以这种方式使用盐会阻止使用@clover 提到的普通彩虹表。

更简单的解决方案通常是更好的解决方案。简单的 rand() 对于密码盐应该足够了。

于 2013-01-21T14:28:35.320 回答