php crypt()河豚盐长度向后兼容

php crypt()河豚盐长度向后兼容,php,salt,blowfish,Php,Salt,Blowfish,我使用crypt()对密码进行哈希运算,使用的是河豚盐,如下所示: [a-zA-Z0-9]中的$2a$,2位,$,21个字符 这里我犯了一个错误,第三个$21后的字符长度不是22。但它工作得很好,所以我没有发现错误 它在我的桌面上运行,运行windows和PHP5.4.4,在AWS ec2上运行,AmazonLinux和PHP5.3.x,但时间太短 有一天,我将AWS php更新为5.5.14。然后问题出现了。crypt()始终返回*0 经过一番尝试,我在盐的末尾加了一美元,所以它变成了22个字

我使用crypt()对密码进行哈希运算,使用的是河豚盐,如下所示:

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

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

它在我的桌面上运行,运行windows和PHP5.4.4,在AWS ec2上运行,AmazonLinux和PHP5.3.x,但时间太短

有一天,我将AWS php更新为5.5.14。然后问题出现了。crypt()始终返回*0

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

但是现在我将这个站点复制到另一台运行openSuSE 13.1和PHP5.5.14的机器上,这个salt再次失败

我将php降级为5.4.20,但没有帮助

新网站仍然需要旧的数据库,所以我必须使密码哈希工作

影响河豚盐长度错误兼容性问题的库或模块是什么?Tt似乎不是PHP的版本。AWS 5.5.14


还是有另一个魔咒能再次救我?我尝试将尾部$替换为[./a-zA-Z0-9]中的每一个,但运气不好,哈希字符串不同….

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

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

看到这个问题的答案了吗

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

编辑:

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

如果降级到PHP5.4,使用(再次)$作为最后一个字符,您的密码应该可以使用

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

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


我还必须建议您使用更新的密码。它将为您提供仅在PHP5.5+上可用的
password_*()
函数。该软件包的作者就是在PHP中实现这些功能的同一个人,因此您可以确保它既安全又100%兼容,在升级到5.5+时为您提供向前兼容性。

与其自己生成salt,不如使用PHP的?Exist系统仍然可以工作。“但是现在我用PHP5.5.14在openSuSE 13.1中构建了另一个站点,这个salt再次失败。“这是同一个系统。只需使用旧数据库复制到另一台具有不同Linux发行版的机器。不管怎样,这就是我问题的重点。我编辑我的问题,让它更清楚。谢谢你的回复,不走运。我试了所有的方法。顺便说一句,哈希的盐部分只包含21个字符。第22个字符不是正确的第22个字符…@JackyJou-你怎么知道盐只包含21个字符?crypt函数可以从“$”中提取一些位,或者填充它。你能给我们看一个你知道密码但用户不使用的散列吗?散列是“$2a$13$XXXXX B9EUUAE7WKKDYE36”,并且在开始时有效。在AWS php 5.3.x和我的Windows 5.4上。4@JackyJou-这是整个散列(?),它的长度应始终为60个字符。散列为“$2a$13$XXXXX B9EUUAE7WKKDYE36”,并在开始时工作。在AWS php 5.3.x和我的Windows 5.4.4上,在我将AWS php更新为5.5.14之后,返回哈希始终为*0,我将salt固定为“$2a$13$xxxxx b9euuae7wkkdye36$”,解决了问题。但现在它在openSuSE 13.1上再次失败,总是返回*0,它运行的是PHP5.5.14或PHP5.4.20。使用“$”在openSuSE 13.1上不起作用,它支持PHP5.4或5.5,但在AWS ec2上起作用,即PHP5.5。。。。我很困惑…嗯。。。嗯,
crypt()
确实依赖于操作系统的底层API,因此从技术上讲,PHP5.5甚至不能保证河豚的可用性。不过,我不知道在常规的PHP5.5设置中如何使用“$”,我对此感到困惑。