问题描述
我观察到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
。
知道我在做什么错吗?
更新:
在password_hash
的官方PHP文档中找到了此提示:
警告:使用PASSWORD_BCRYPT作为算法,将导致password参数被截断,最大长度为72个字符。
然后我进行了检查,实际上,修改AAMkAGEzN2EyZTg4LWRiNTUtNGIwYS04ZTA1LWE2Y2U5OTRjYjQ0ZgBGAAAAAACxCzc14g3e
后面的任何字符都不会改变结果,例如交换最后e
与f
返回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个字符。