【问题标题】:Crypt function outputting two different values depending on PHP versionCrypt 函数根据 PHP 版本输出两个不同的值
【发布时间】:2015-08-07 07:16:36
【问题描述】:

在以下代码中使用密码“testtest”和哈希“KFtIFW1vulG5nUH3a0Mv”会产生不同的哈希,具体取决于 PHP 版本(如下图所示):

$salt = "KFtIFW1vulG5nUH3a0Mv";
$password = "testtest";

$key = '$2a$07$';
$key = $key.$salt."$"; 

echo crypt($password, $key);

输出 1(PHP v.5.3.0 - 5.4.41、5.5.21 - 5.5.25、5.6.5 - 5.6.9):$2a$07$KFtIFW1vulG5nUH3a0Mv$.0imhrNa/laTsN0Ioj5m357/a8AxxF2q

输出 2(PHP v.5.5.0 - 5.5.20、5.6.0 - 5.6.4):$2a$07$KFtIFW1vulG5nUH3a0Mv$e0imhrNa/laTsN0Ioj5m357/a8AxxF2q

这是一个问题的例子: http://3v4l.org/dikci

如果使用 crypt 对登录密码进行哈希处理,这是一个大问题,因为根据 PHP 版本,哈希值会有所不同。有谁知道这个问题是从哪里来的以及如何处理的?

【问题讨论】:

  • define "取决于 PHP 版本" 并阅读手册php.net/crypt
  • 看一下附图,某些PHP版本输出的结果与其他版本不同。我现在将添加详细信息。
  • 我在高分辨率;很难看到它;需要眯眼
  • 已编辑以包含版本
  • 看看这是否回答了它codechewing.com/library/…

标签: php hash passwords crypt


【解决方案1】:

这并不是你想象的那么大的问题。

首先您应该注意,您的代码并非绝对正确,BCrypt 需要 22 个字符的盐,但您提供了 20 个字符的盐。这意味着终止的“$”(顺便说一句,这不是必需的)将被视为盐的一部分,以及密码的第一个字母。 $ 不是 BCrypt 盐的有效字符。

要考虑的另一件事是,并非字符 22 的所有位都被使用,这是由于编码的原因,ircmaxell 对此给出了good explanation。所以不同的盐可以产生相同的哈希,你可以在answer 中很好地看到这一点。理论上,不同的实现如何处理字符 22 的最后一位可能会发生变化。只要 crypt 函数可以用两个哈希值验证密码就没有问题。

salt 的产生及其陷阱是原因之一,为什么 password_hash()password_verify() 编写的函数使密码处理更加容易。

【讨论】:

  • 你是绝对正确的,将 salt 更改为 22 个字符会导致输出一致。
  • @JimmyBanks - 这些例子确实有点误导,评论说:These salts are examples only, and should not be used verbatim in your code. You should generate a distinct, correctly-formatted salt for each password.。此外,他们使用现在应该用“2y”替换的算法“2a”。似乎他们忘记更新文档了,可能是因为无论如何都应该使用password_hash() 函数。
  • @JimmyBanks - 如果您不确定并需要“官方”来源是否需要 $,您可以查看 password_hash() 函数的 compatibility pack。在第 150 行的某处,您可以看到 salt 是如何生成的,该函数是由编写 password_hash() 函数的同一作者编写的。最后但同样重要的是,看看 PHP 代码本身,它是免费提供的 ;-)
猜你喜欢
  • 2012-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
相关资源
最近更新 更多