【问题标题】:password_verify works in PHP 7.4 but doesn't work in PHP 8.2password_verify 在 PHP 7.4 中有效,但在 PHP 8.2 中无效
【发布时间】:2023-02-21 19:03:42
【问题描述】:

我有两个 docker 容器,一个是 PHP 8.2.3,另一个是 PHP 7.4.30。

另外,我有包含现有密码哈希的数据库(最初由 Yii2 框架创建,使用密码 password_hash,在未知环境中)。

我制作了 test.php,输出了两件事:

var_dump(password_get_info('$2a$07$6c2eb62b00df224f3d20$.qzdiDRZejMnGytXWsA7Jid7RpWazDc6'))

var_dump(password_verify('password', '$2a$07$6c2eb62b00df224f3d20$.qzdiDRZejMnGytXWsA7Jid7RpWazDc6'))

在 PHP 7.4 中,结果是:

array(3) {
  ["algo"]=>
  NULL
  ["algoName"]=>
  string(7) "unknown"
  ["options"]=>
  array(0) {
  }
}

bool(true)

在 PHP 8.2 中:

array(3) {
  ["algo"]=>
  NULL
  ["algoName"]=>
  string(7) "unknown"
  ["options"]=>
  array(0) {
  }
}

bool(false)

我知道可能使用了不同的哈希算法。但是应该在散列本身中指定(并因此识别)散列算法。

另外,两个引擎都不知道算法。但是,PHP 7.4 能够验证密码。

为什么会这样?

从文档:

请注意,password_hash() 返回算法、成本和盐作为一部分 返回的哈希值。因此,需要的所有信息 验证哈希是否包含在其中。这允许验证功能 验证散列而无需单独存储盐或

【问题讨论】:

标签: php


【解决方案1】:

你受到了this fix的影响:

格式错误的 BCrypt 散列在其 salt 部分中包含 $ 将触发缓冲区重读,并可能错误地将任何密码验证为有效。

[..]

“PHP Hack”自 PHP 自己的第一个版本 crypt_blowfish 实现以来就存在,并且在评论或提交历史中没有给出明确的理由来证明它的存在。在任何情况下,这样的哈希都不是有效的 BCrypt 哈希,它不是由 password_hash() 生成的,这是 PHP 中推荐的密码哈希 API。

虽然这在技术上可能会破坏与现有用户的向后兼容性,但事实上这些哈希值从未由 password_hash() 生成,不被 BCrypt 的其他实现所接受,并在应用程序中引入可能的安全漏洞,它们应该在每个受支持的 PHP 版本中被拒绝。

https://github.com/php/php-src/security/advisories/GHSA-7fj2-8x79-rjf4

这里的重点是您的哈希从一开始就在技术上显然是无效的,并且根本不应该存在。

【讨论】:

    猜你喜欢
    • 2015-02-05
    • 2017-07-12
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 2012-11-06
    • 2017-07-23
    相关资源
    最近更新 更多