Laravel 5:在相同的字符串上使用bcrypt会给出不同的值

问题描述 投票:8回答:2

我正在使用Laravel的bcrypt函数来散列密码。当我做,

bcrypt('secret')

我明白了

=> "$2y$10$mnPgYt2xm9pxb/c2I.SH.uuhgrOj4WajDQTJYssUbTjmPOcgQybcu"

但是,如果我再次运行它,我会得到

=> "$2y$10$J8h.Xmf6muivJ4bDweUlcu/BaNzI2wlBiAcop30PbPoKa0kDaf9xi"

等等...

那么,如果每次都得到不同的值,密码匹配过程是否会失败?

laravel laravel-5 bcrypt
2个回答
20
投票

这就是bcrypt应该如何运作的方式。见wikipedia

Bcrypt在散列期间生成随机的128位盐。这个盐成为哈希的一部分,因此我们总是为相同的输入字符串获得不同的哈希值。随机盐实际上用于阻止暴力攻击。

由于哈希值不同,密码匹配过程不会失败。在tinker中尝试以下操作

$hash1 = bcrypt('secret')
$hash2 = bcrypt('secret')

Hash::check('secret', $hash1)
Hash::check('secret', $hash2)

你应该在true的情况下获得Hash::check

因此,即使哈希值不同,密码匹配也不会失败。


0
投票

Bcrypt使用128位盐并加密192位魔术值。它利用了eksblowfish中昂贵的密钥设置。

bcrypt算法分两个阶段运行,如图3所示。在第一阶段,使用cost,salt和password调用EksBlowfishSetup来初始化eksblowfish的状态。 bcrypt的大部分时间花费在昂贵的密钥安排上。之后,使用ECB模式下的eksblowfish和前一阶段的状态,将192位值“OrpheanBeholderScryDoubt”加密64次。输出是成本和128位盐与加密循环的结果连接在一起。

enter image description here

它如何在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支持的选项:

salt(字符串) - 在散列密码时手动提供盐。请注意,这将覆盖并防止自动生成salt。

如果省略,则每个密码哈希值都会通过password_hash()生成随机盐。这是预期的操作模式。

警告自PHP 7.0.0起,salt选项已被弃用。现在优选简单地使用默认生成的盐。

cost(整数) - 表示应该使用的算法成本。可以在crypt()页面上找到这些值的示例。

如果省略,将使用默认值10。这是一个很好的基准成本,但您可能需要考虑根据您的硬件增加它。

Bcrypt加密和解密如何工作: 内部bcrypt()使用PHP的内置password_hash()函数。 password_hash()每次都返回不同的值,因为它会在密码中附加一个随机字符串(“salt”)。 salt实际上包含在输出哈希中。

如果使用相同的盐对相同的密码进行哈希处理,则始终会获得相同的输出。因此,password_verify()查看存储的哈希,提取salt,然后使用相同的盐哈希给定的密码。

© www.soinside.com 2019 - 2024. All rights reserved.