Laravel:Hash :: check为两条不同的消息返回“ true”

问题描述

我观察到Laravel的Hash Facade使用Hash::make()创建摘要(与bcrypt并将其保存到数据库中的行为非常奇怪。例如,纯文本

AAMkAGEzN2EyZTg4LWRiNTUtNGIwYS04ZTA1LWE2Y2U5OTRjYjQ0ZgBGAAAAAACxCzc14g3eSoadAxaGpB3ABwCr5qkyxHH4QY9vHKr6u5IrAAAAAAENAACr5qkyxHH4QY9vHKr6u5IrAARi2BmGAAA=

产生$2y$10$fq6jvoNL/RShVKfNDy64EOGW0gLzd0GvfS.di16Z9LcCK7DpIHONK

现在,将Hash::check()与上述纯文本和摘要一起使用时,当然会返回true。但是,更改纯文本中的一个字符(例如,用A替换最后一个B),并根据相同的摘要对其进行检查,也会返回true

>>> Hash::check('AAMkAGEzN2EyZTg4LWRiNTUtNGIwYS04ZTA1LWE2Y2U5OTRjYjQ0ZgBGAAAAAACxCzc14g3eSoadAxaGpB3ABwCr5qkyxHH4QY9vHKr6u5IrAAAAAAENAACr5qkyxHH4QY9vHKr6u5IrAARi2BmGAAA=','$2y$10$fq6jvoNL/RShVKfNDy64EOGW0gLzd0GvfS.di16Z9LcCK7DpIHONK')
=> true
>>> Hash::check('AAMkAGEzN2EyZTg4LWRiNTUtNGIwYS04ZTA1LWE2Y2U5OTRjYjQ0ZgBGAAAAAACxCzc14g3eSoadAxaGpB3ABwCr5qkyxHH4QY9vHKr6u5IrAAAAAAENAACr5qkyxHH4QY9vHKr6u5IrAARi2BmGAAB=','$2y$10$fq6jvoNL/RShVKfNDy64EOGW0gLzd0GvfS.di16Z9LcCK7DpIHONK')
=> true
>>> Hash::check('AAMkAGEzN2EyZTg4LWRiNTUtNGIwYS04ZTA1LWE2Y2U5OTRjYjQ0ZgBGAAAAAACxCzc14g3eSoadAxaGpB3ABwCr5qkyxHH4QY9vHKr6u5IrAAAAAAENAACr5qkyxHH4QY9vHKr6u5IrAARi2BmGAAC=','$2y$10$fq6jvoNL/RShVKfNDy64EOGW0gLzd0GvfS.di16Z9LcCK7DpIHONK')
=> true

根据我的理解,这不可能实现什么散列,但这似乎不是冲突,因为将B替换为C也会产生true

我正在使用Laravel 8.0和PHP 7.4.11。

知道我在做什么错吗?

更新: 在password_hash的官方PHP文档中找到了此提示

警告:使用PASSWORD_BCRYPT作为算法,将导致password参数被截断,最大长度为72个字符。

然后我进行了检查,实际上,修改AAMkAGEzN2EyZTg4LWRiNTUtNGIwYS04ZTA1LWE2Y2U5OTRjYjQ0ZgBGAAAAAACxCzc14g3e后面的任何字符都不会改变结果,例如交换最后ef返回false的{​​{1}}。字符串的长度为Hash::check()个字符,因此可能是截断的结果。 但是为什么??Laravel 72文档中没有提到这一点。我有几个长度超过72个字符的密码,所以密码的结尾实际上并不重要?

因此,我需要使用Laravel的另一个功能来哈希较长的消息吗?哪一个

解决方法

我做了一些研究并得出以下结论:

the official laravel docs中,他们指的是php's official docs。他们在caution的{​​{1}}部分说:

使用PASSWORD_BCRYPT作为算法,将导致password参数被截断,最大长度为72个字符。

我检查了您的字符串,它的长度为152。因此,在您的情况下,您应该使用其他算法(可以在password的{​​{1}}中设置此算法)或确保输入字符串最大为72个字符。