【问题标题】:php crypt() blowfish salt length backward compatiblephp crypt() 河豚盐长度向后兼容
【发布时间】:2014-07-17 09:39:03
【问题描述】:

我使用 crypt() 对密码进行哈希处理,使用这样的河豚盐:

$2a$,2 位数字,$,[a-zA-Z0-9] 中的 21 个字符

这里我犯了一个错误,第三个 $ 之后的字符长度是 21 而不是 22。但它工作正常,所以我没有发现错误。

它适用于我的运行 windows 和 php 5.4.4 的桌面以及运行 Amazon linux 和 php 5.3.x 的 AWS ec2,但盐太短了。

有一天我将 AWS php 更新到 5.5.14。然后问题发生了。 crypt() 一直返回 *0。

经过一番尝试,我在盐的末尾添加了一个 $ ,所以它变成了 22 个字符。它再次工作并返回与以前相同的哈希字符串。虽然它不遵守河豚规则,但字符应该是 [./a-zA-Z0-9]

但是现在我将这个站点复制到另一台运行 openSuSE 13.1 和 php 5.5.14 的机器上,这个盐又失败了。

我将 php 降级到 5.4.20 但没有帮助。

新站点仍然需要旧数据库,所以我必须使密码哈希有效。

影响这个河豚盐长度错误兼容性问题的库或模块是什么? tt好像不是PHP的版本。 AWS 5.5.14

或者还有别的魔法字符可以再次拯救我吗?我尝试将尾 $ 替换为 [./a-zA-Z0-9] 中的每个,但不幸运,哈希字符串不同....

【问题讨论】:

  • 与其自己生成盐,不如使用 PHP 的hashing functions
  • 现有系统需要继续工作。
  • “但是现在我在 openSuSE 13.1 中使用 php 5.5.14 构建了另一个站点,这种盐又失败了。”
  • 那是同一个系统。只需使用旧数据库复制到具有不同 Linux 发行版的另一台机器。无论如何,这就是我的问题的重点。
  • 我编辑我的问题以使其更清楚。感谢您的回复。

标签: php salt blowfish


【解决方案1】:

首先我强烈建议使用新函数password_hash()password_verify() 来生成和验证新的哈希值。当然,这并不能解决您使用旧哈希的实际问题,但最好将它们标记为旧哈希,以便下次用户登录时更新它们。

对于这个旧的哈希,我会尝试验证它们,生成具有有效最后一个字符 22 的盐。crypt 函数实际上只使用字符 22 的部分位(盐的 126 位而不是 128 位)。所以最后一个字符 22 的组将在相同的哈希值中结束。

查看这个问题的答案Why does crypt/blowfish generate the same hash...

如果您尝试将所有相关字符 [.Oeu] 作为字符 22,则很有可能一种组合会产生与您的无效盐相同的结果。

编辑:

由于使用的盐成为密码哈希的一部分,您应该能够看到用作字符 22(第三个 $ 之后的第 22 个字符)的内容。

【讨论】:

  • 运气不好。我尝试了所有允许的字符。顺便说一句,哈希的盐部分仅包含 21 个字符。第 22 个字符不是正确的第 22 个盐 ...
  • @JackyJou - 你怎么知道盐只包含 21 个字符? crypt 函数可以从 '$' 中获取一些位或填充它。您能否向我们展示这样一个哈希值,一个您知道密码但未被用户使用的哈希值?
  • 哈希值是 '$2a$13$xxxxxB9EUUAe7wKKdye36',并且开始工作。在 AWS php 5.3.x 和我的 Windows 5.4.4
  • @JackyJou - 这是整个哈希(?),它应该总是有 60 个字符的长度。
  • 哈希值是 '$2a$13$xxxxxB9EUUAe7wKKdye36',并且开始工作。在我将 AWS php 更新到 5.5.14 后,在 AWS php 5.3.x 和我的 Windows 5.4.4 上,返回哈希始终为 *0,我将盐固定为“$2a$13$xxxxxB9EUUAe7wKKdye36$”,这解决了问题。但是现在它再次在 openSuSE 13.1 上失败了,总是返回 *0 ,它正在运行 PHP 5.5.14 或 PHP 5.4.20。
【解决方案2】:

使用(再次)“$”作为最后一个字符应该可以使您的密码如果您降级到 PHP 5.4。

但是,这不是一个长期的解决方案。使用“$”作为最后一个字符会使您的所有密码向前不兼容,因为这不是有效的 Base64 字符(无论是常规的还是与 bcrypt 兼容的 Base64)。

只要您可以使用 PHP 5.4,这意味着只要 PHP 5.4 得到官方支持,您就应该在使用所有旧密码时对其进行重新哈希处理。 放弃 PHP 5.4 支持后,您别无选择,只能为仍然使用旧哈希方案的用户生成新的随机密码并通过电子邮件发送给他们。

我还必须建议您使用password-compat package 更新密码。它将为您提供 password_*() 函数,这些函数仅在 PHP 5.5+ 上可用。该包的作者是 PHP 本身实现功能的同一人,因此您可以确定它既安全又 100% 兼容,为您升级到 5.5+ 时提供向前兼容。

【讨论】:

  • use '$' 在 openSuSE 13.1 上不起作用,它支持 php 5.4 或 5.5,但适用于 AWS ec2,即 php 5.5 .... 我很困惑 ...
  • 嗯...嗯,crypt() 确实依赖于操作系统的底层 API,所以从技术上讲,拥有 PHP 5.5 甚至不能保证 Blowfish 的可用性。我不明白你如何在常规的 PHP 5.5 设置中使用 '$',但我对此感到困惑。
猜你喜欢
  • 2011-06-08
  • 1970-01-01
  • 2012-11-13
  • 1970-01-01
  • 1970-01-01
  • 2012-01-10
  • 2014-09-05
  • 1970-01-01
  • 2013-01-04
相关资源
最近更新 更多