升级使用无效 CRYPT_STD_DES 盐生成的 PHP(<5.3.2)密码 [关闭]

Posted

技术标签:

【中文标题】升级使用无效 CRYPT_STD_DES 盐生成的 PHP(<5.3.2)密码 [关闭]【英文标题】:Upgrading PHP (<5.3.2) passwords generated using invalid CRYPT_STD_DES salt [closed] 【发布时间】:2020-08-29 01:42:47 【问题描述】:

长话短说,我有一些密码在 php 版本中未正确加盐和散列,如果加盐无效,则允许 crypt() 函数回退到 CRYPT_STD_DES 算法。

但是在 PHP 5.3.2+ 中:

5.3.2 修复了 Blowfish 在无效回合中的行为以返回“失败”字符串(“*0”或“*1”),而不是回退到 DES。

造成这个问题的原因是盐包含“$”字符,因为它原本是河豚盐(但在不知不觉中格式错误)。

因此,我无法手动执行以下操作: crypt($pass, "$a"); 因为那现在也不是有效的 CRYPT_STD_DES 盐。盐必须在“./0-9A-Za-z”范围内。它只是按照 PHP 开发人员的意图返回“*0”。

如何在更新的 PHP 版本(至少 7.1,理想情况下)中验证这些格式错误的密码?

【问题讨论】:

如果创建了 DES 哈希,它包含什么盐,它真的包含 $ 字符吗?你能显示这样一个 DES 哈希字符串的第一部分吗? @martinstoeckli 在这种情况下盐是“$2”。哈希的开头(例如)将是“$281kuD”加上另外 6 个字符。 【参考方案1】:

你可能正在寻找

password_hash ( string $password , int $algo [, array $options ] ) : string

https://www.php.net/manual/en/function.password-hash.php

【讨论】:

该函数仅用于对密码进行哈希处理。在升级到现代哈希算法之前,我需要先验证它们。【参考方案2】:

作为一种解决方法,我最终将旧版本的 PHP 用于单个目录,我可以在其中进行 file_get_contents() 调用并使用旧(错误)算法检索哈希,但仍然使用更现代的版本PHP 其他地方。

然而,这不是一个合适的解决方案,因为它在技术上不能回答这个问题: “如何在更新的 PHP 版本中验证这些格式错误的密码?”

因此,除非似乎没有其他可能的解决方案,否则我不会将此标记为已接受的答案(但我认为为了完整起见应该添加此答案)。

【讨论】:

【参考方案3】:

找到了一个实际的解决方案。通过暴力破解盐,事实证明 PHP 将无效的“$2”STD_DES 盐解释为“q2”。

因此,这个问题的答案是,可以在较新版本的 PHP 中验证这些哈希,方法是更改​​用于比较哈希的盐,使其以“q2”而不是“$2”开头。 从那里,可以在执行相等检查时调用substr_replace($str, '$', 0, 1); 将新添加的“q”字符替换回“$”字符。

作为轶事,显然我所掌握的信息不正确,并且哈希是在 PHP 5.3.29 中生成的,这与文档所说的回退到 STD_DES 在版本 5.3.2 中修补的说法相矛盾。

【讨论】:

以上是关于升级使用无效 CRYPT_STD_DES 盐生成的 PHP(<5.3.2)密码 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何最好地为网站生成随机盐?

crypt():没有指定盐参数。您必须使用随机生成的盐和强哈希函数来生成安全哈希 [重复]

密码的加盐加密

RAND() 是不是具有低熵来生成盐?

OpenSSL - 密码与盐目的

生成用于创建密码检索令牌的随机“站点盐”的好方法是啥?