一尘不染

如何将Argon2算法与password_hash一起使用?

algorithm

因此,我听说PHP
7.2引入了新的Argon2算法。但是我对如何在现有代码中使用它感到困惑。例如,我有这个

$password = password_hash('somepassword', PASSWORD_DEFAULT, ['cost' => 12]);

PASSWORD_DEFAULT现在是否使用Argon2?我需要更改什么(如果有的话)password_verify?bcrypt现在被认为是不安全的吗?


阅读 753

收藏
2020-07-28

共1个答案

一尘不染

什么是Argon2?bcrypt现在不好了吗?

在PHP
7.2之前,唯一使用的哈希算法password_hash是bcrypt。在撰写本文时,bcrypt仍然被认为是一个强大的哈希值,尤其是相对于它的前辈,md5以及sha1(这两者都是不安全的,因为它们是快速)。Argon2
只是暴力破解的一种更昂贵的算法

Argon2i使用与数据无关的内存访问。它之所以速度较慢,是因为它在内存中进行了更多的传递,以防止受到权衡攻击。强烈建议您使用密码哈希和基于密码的密钥派生。

Bcrypt仍然是可接受的密码哈希。如果不想(从7.2.0版本开始),则无需切换。另外,PASSWORD_DEFAULT仅应在下一个完整版本(7.3.0或更高版本)上更改(根据PHP内部策略)。如果要确保仅继续使用bcrypt,则可以PASSWORD_BCRYPT改用。但是,这是不必要的,我们将在下面讨论。

您如何使用Argon2?

首先,我们将password_hashover 的第二个参数切换为其中一个常量

  • PASSWORD_ARGON2I -PHP 7.2.0+
  • PASSWORD_ARGON2ID -PHP 7.3.0+(首选,如果可用,请参见下面的注释)

然后我们需要更改选项。bcrypt使用它cost作为参数来遍历密码多少次(更高的成本=更长的哈希时间)。但是有不同的成本因素

password_hash('somepassword', PASSWORD_ARGON2I, ['memory_cost' => 2048, 'time_cost' => 4, 'threads' => 3]);

从手册中我们可以看到这些选项的作用

  • memory_cost -可用于计算Argon2哈希的最大内存(以字节为单位)(默认为1024)
  • time_cost -计算Argon2哈希值可能需要的最长时间(默认值为2)
  • threads -用于计算Argon2哈希值的线程数(默认为2)

在更改这些内容之前,请了解,此处较高的成本 会降低脚本的速度
。您需要在服务器上运行测试以找到最适合您的设置。这通常是通过遍历给定成本的几次迭代来完成的。如果需要,PHP手册提供了一个示例

还要注意,虽然bcrypt存储60个字符,但Argon2可能需要更多字符。理想情况下,您应该使密码字段存储255个字符。

我们要改变password_verify什么?

答案是……什么都没有。知道这password_verify足够聪明,可以弄清楚使用了哪种算法并适当地处理它。如上所述,这意味着如果您使用PASSWORD_DEFAULT,则默认值可以更改并且不会对您造成负面影响(尽管您可能需要调整成本参数)。password_verify只是需要它支持的算法。如果您从bcrypt切换到Argon2,则两者都会以相同的方式进行验证,因为所有必需的数据(盐,哈希和成本)都将为您存储。

//Works for both bcrypt and Argon2
if(password_verify($user_password, $stored_hash)) {
    // password validated
}

如果要从bcrypt升级哈希,则可以在用户成功登录(从而为您提供未加密的密码)后执行此操作。只需检查您的哈希是否以$2y$(bcrypt标记)开头即可。如果是这样,请password_hash再次将提供的密码与Argon2参数一起传递给,然后将其保存到登录用户的密码字段中。

什么是Argon2ID?

如在此Crypto.SE问题中所述,PHP
7.3
中引入了Argon2ID,它对Argon2I进行了一些改进。

1-pass Argon2id的最佳折衷攻击是组合的低存储攻击(针对内存的前半部分)和排名攻击(针对后半部分),其综合系数约为2.1。

Argon2ID使用与Argon2I相同的参数。

2020-07-28