我确实对crypt()PHP函数感到困惑。
当第二个crypt明显使用不同的第二个参数时,以下两个crypt函数如何提供相同的输出? Diff salt意味着diff hash对吗?
echo crypt("password", '$2y$09$anexamplestringforsalt$')."\n<br>";
echo crypt("password", crypt("password", '$2y$09$anexamplestringforsalt$'))."\n<br>";
输出:
$2y$09$anexamplestringforsale/.K.VdgECUVEd9N4ja3u1WtgPi5BXZq
答案 0 :(得分:11)
原因是因为salt是crypt提供的哈希输出的一部分。
$2y$09$anexamplestringforsale/.K.VdgECUVEd9N4ja3u1WtgPi5BXZq
分为几个部分:
2y
- 算法标识符(bcrypt)09
- 费用参数anexamplestringforsale
- 盐/.K.VdgECUVEd9N4ja3u1WtgPi5BXZq
- 哈希这样就可以直接使用结果哈希作为验证调用中的salt。
$hash = crypt($password, $salt);
if ($hash === crypt($password, $hash)) {
现在您不需要分别存储算法,成本或盐。只需将它们直接存储在哈希结果中即可。简单。
此外,我强烈建议您使用简化密码哈希API,该API专门用于缓解这些问题:password_hash()。
答案 1 :(得分:0)
如果您使用BlowFish算法,您的代码将最终运行到此功能中:BF_crypt(源代码)
声明:
static char *BF_crypt(const char *key, const char *setting,
char *output, int size,
BF_word min)
密钥是$ str,设置是php函数string crypt ( string $str [, string $salt ] )
的$ salt,输出将是加密的返回值。
如您在源代码中所见:
首先,在第777行memcpy(output, setting, 7 + 22 - 1);
处,此行将$ salt的前29个字符(从pos 0到pos 7 + 22 -1)复制到返回值$2y$09$anexamplestringforsale
< / p>
第二,$ salt的剩余部分从未使用过。
第三,在第784行BF_encode(&output[7 + 22], data.binary.output, 23);
处,将加密的字符串附加在返回值上。
因此,$ str和$ salt的前29个字符是影响您的返回值的因素。