目前认为MD5是部分不安全的。考虑到这一点,我想知道使用哪种机制来保护密码。

这个问题,“双重哈希”密码是否比只哈希一次更不安全? 建议哈希多次可能是一个好主意,而如何实现个别文件的密码保护?建议使用盐。

我用的是PHP。我想要一个安全快捷的密码加密系统。对一个密码进行一百万次哈希运算可能更安全,但也更慢。如何在速度和安全之间取得良好的平衡?此外,我更希望结果具有恒定数量的字符。

哈希机制必须在PHP中可用 必须是安全的 它可以使用盐(在这种情况下,所有的盐都一样好吗?有没有办法生产出好的盐?)

另外,我是否应该在数据库中存储两个字段(例如,一个使用MD5,另一个使用SHA)?这会让它更安全还是更不安全?

以防我不够清楚,我想知道要使用哪个哈希函数,以及如何选择一个好的盐,以便拥有一个安全和快速的密码保护机制。

没有完全涵盖我的问题的相关问题:

PHP中的SHA和MD5有什么区别 简单密码加密 为asp.net存储密钥和密码的安全方法 如何在Tomcat 5.5中实现加盐密码


当前回答

从PHP 5.5开始,PHP就有了简单安全的散列和验证密码的函数password_hash()和password_verify()

$password = 'anna';
$hash = password_hash($password, PASSWORD_DEFAULT);
$expensiveHash = password_hash($password, PASSWORD_DEFAULT, array('cost' => 20));

password_verify('anna', $hash); //Returns true
password_verify('anna', $expensiveHash); //Also returns true
password_verify('elsa', $hash); //Returns false

当使用password_hash()时,它生成一个随机的盐并将其包含在输出的哈希中(以及使用的代价和算法)。password_verify()然后读取该哈希并确定使用的盐和加密方法,并根据提供的明文密码验证它。

提供PASSWORD_DEFAULT指示PHP使用已安装的PHP版本的默认哈希算法。具体哪种算法在未来的版本中会随着时间的推移而改变,因此它将始终是可用的最强算法之一。

不断增加的成本(默认为10)使得哈希更难使用暴力,但也意味着生成哈希并根据它们验证密码将为服务器的CPU带来更多的工作。

请注意,即使默认的哈希算法可能会改变,旧的哈希将继续进行验证,因为所使用的算法存储在哈希中,password_verify()会捕获它。

其他回答

我只想指出,PHP 5.5包含一个密码哈希API,它提供了crypt()的包装器。这个API极大地简化了哈希、验证和重哈希密码哈希的任务。作者还发布了一个兼容性包(以您只需要使用的单个password.php文件的形式),供那些使用PHP 5.3.7及以后版本并希望立即使用它的用户使用。

它目前只支持BCRYPT,但它的目标是轻松扩展到包括其他密码哈希技术,因为技术和成本存储为哈希的一部分,对您首选的哈希技术/成本的更改不会使当前哈希失效,框架将自动地在验证时使用正确的技术/成本。如果您没有显式地定义自己的盐,它还可以处理生成“安全”盐。

API公开了四个函数:

Password_get_info() -返回关于给定散列的信息 Password_hash()—创建密码散列 Password_needs_rehash()—检查给定的散列是否与给定的选项匹配。有用的检查散列是否符合您当前的技术/成本方案,允许您在必要时重新散列 Password_verify()—验证密码是否与散列匹配

目前,这些函数接受PASSWORD_BCRYPT和PASSWORD_DEFAULT密码常量,它们目前是同义词,区别在于PASSWORD_DEFAULT“在支持更新、更强的散列算法的新PHP版本中可能会改变”。在登录时使用PASSWORD_DEFAULT和password_needs_rehash()(并在必要时重新进行散列)应该确保您的散列对暴力攻击具有合理的弹性,几乎不需要做任何工作。

编辑:我刚刚意识到罗伯特·K的回答中简单提到了这一点。我将把这个答案留在这里,因为我认为它提供了更多关于它如何工作的信息,以及它为那些不了解安全性的人提供的易用性。

一个更简短、更安全的答案是:完全不要编写自己的密码机制,使用经过验证和测试的机制。

PHP 5.5或更高版本:password_hash()质量很好,是PHP核心的一部分。 PHP 4。x(过时):OpenWall的phpass库比大多数自定义代码(用于WordPress、Drupal等)要好得多。

大多数程序员只是不具备在不引入漏洞的情况下安全地编写加密相关代码的专业知识。

快速自测:什么是密码拉伸,应该使用多少次迭代?如果你不知道答案,你应该使用password_hash(),因为密码扩展现在是密码机制的一个关键特性,这是由于更快的cpu和gpu和fpga的使用,以每秒数十亿次的猜测速度破解密码(gpu)。

截至2012年,你可以在5台台式电脑上安装25个图形处理器,在6小时内破解所有8个字符的Windows密码。这是强制的,即枚举和检查每个8个字符的Windows密码,包括特殊字符,而不是字典攻击。有了现代gpu,你当然可以破解更多的密码,或者使用更少的gpu——或者以合理的价格在云中租用gpu几个小时。

还有很多针对Windows密码的彩虹表攻击,它们运行在普通cpu上,速度非常快。

这一切都是因为,即使在Windows 10中,Windows也没有对密码进行腌制或拉伸。2021年依然如此。不要犯和微软一样的错误!

参见:

很好的回答,更多关于为什么password_hash()或phpass是最好的方法。 一篇很好的博客文章,给出了主要算法的推荐“工作因子”(迭代次数),包括bcrypt, scrypt和PBKDF2。

最后,在数学上,双重哈希没有任何好处。然而,在实践中,它对于防止基于彩虹表的攻击是有用的。换句话说,它并不比使用salt进行哈希更有好处,后者在应用程序或服务器上占用的处理器时间要少得多。

谷歌表示SHA256对PHP可用。

你一定要加盐。我建议使用随机字节(不要限制自己使用字符和数字)。通常情况下,你选择的时间越长,就越安全、越慢。64字节应该就可以了。

从PHP 5.5开始,PHP就有了简单安全的散列和验证密码的函数password_hash()和password_verify()

$password = 'anna';
$hash = password_hash($password, PASSWORD_DEFAULT);
$expensiveHash = password_hash($password, PASSWORD_DEFAULT, array('cost' => 20));

password_verify('anna', $hash); //Returns true
password_verify('anna', $expensiveHash); //Also returns true
password_verify('elsa', $hash); //Returns false

当使用password_hash()时,它生成一个随机的盐并将其包含在输出的哈希中(以及使用的代价和算法)。password_verify()然后读取该哈希并确定使用的盐和加密方法,并根据提供的明文密码验证它。

提供PASSWORD_DEFAULT指示PHP使用已安装的PHP版本的默认哈希算法。具体哪种算法在未来的版本中会随着时间的推移而改变,因此它将始终是可用的最强算法之一。

不断增加的成本(默认为10)使得哈希更难使用暴力,但也意味着生成哈希并根据它们验证密码将为服务器的CPU带来更多的工作。

请注意,即使默认的哈希算法可能会改变,旧的哈希将继续进行验证,因为所使用的算法存储在哈希中,password_verify()会捕获它。