我使用Laravel的bcrypt
函数来散列密码。当我这样做时,
bcrypt('secret')
我得到了
=> "$2y$10$mnPgYt2xm9pxb/c2I.SH.uuhgrOj4WajDQTJYssUbTjmPOcgQybcu"
但是,如果我再次运行它,我会
=> "$2y$10$J8h.Xmf6muivJ4bDweUlcu/BaNzI2wlBiAcop30PbPoKa0kDaf9xi"
依旧......
那么,如果每次都得到不同的值,密码匹配过程是否会失败?
答案 0 :(得分:20)
这就是bcrypt
的工作方式。请参阅wikipedia。
Bcrypt在散列期间生成随机128位salt 。此 salt 成为哈希的一部分,因此我们总是为同一输入字符串获取不同的哈希值。随机盐实际上用于阻止暴力攻击。
由于哈希值不同,密码匹配过程不会失败。
请在tinker
$hash1 = bcrypt('secret')
$hash2 = bcrypt('secret')
Hash::check('secret', $hash1)
Hash::check('secret', $hash2)
true
。
Hash::check
。{/ 1}
因此,即使哈希值不同,密码匹配也不会失败。
答案 1 :(得分:0)
Bcrypt 使用128位的salt并加密192位的magic值。它利用了eksblowfish中昂贵的密钥设置。
bcrypt算法分两个阶段运行,如图3所示。在第一个阶段,使用成本,盐和密码调用EksBlowfishSetup来初始化eksblowfish的状态。 bcrypt的大部分时间都花在了昂贵的密钥调度中。然后,使用eksblowfish在ECB模式下以前一阶段的状态加密192位值``OrpheanBeholderScryDoubt''64次。输出是成本和128位盐与加密循环的结果连接在一起。
它在laravel中如何工作:
if (! function_exists('bcrypt')) {
/**
* Hash the given value against the bcrypt algorithm.
*
* @param string $value
* @param array $options
* @return string
*/
function bcrypt($value, $options = [])
{
return app('hash')->driver('bcrypt')->make($value, $options);
}
}
PASSWORD_BCRYPT支持的选项:
盐(字符串)-在散列密码时手动提供盐。请注意,这将覆盖并阻止盐自动生成。
如果省略,password_hash()将为散列的每个密码生成随机盐。这是预期的操作模式。
警告从PHP 7.0.0起不建议使用salt选项。就是现在 首选仅使用默认情况下生成的盐。
费用(整数)-表示应使用的算法费用。这些值的示例可以在crypt()页面上找到。
如果省略,将使用默认值10。这是一个不错的基准成本,但是您可能要考虑根据硬件而增加它。
Bcrypt加密和解密的工作方式:
内部使用bcrypt()会使用PHP的内置password_hash()函数。 password_hash()每次都会返回不同的值,因为它会在密码后附加一个随机字符串(“ salt”)。盐实际上包含在输出哈希中。
如果使用相同的盐对相同的密码进行哈希处理,则将始终获得相同的输出。因此password_verify()会查看存储的哈希,提取盐,然后使用相同的盐对给定的密码进行哈希处理。