因为发现密码重新生成(密码值不变)时,返回的 hash 值都会变化,而解密却都能够成功,所以对 Laravel 自带的这个获取加密 hash 值的方法突然比较好奇。

\vendor\laravel\framework\src\Illuminate\Foundation\helpers.php

if (! function_exists('bcrypt')) {
    /**
     * Hash the given value.
     *
     * @param  string  $value
     * @param  array   $options
     * @return string
     */
    function bcrypt($value, $options = [])
    {
        return app('hash')->make($value, $options);
    }
}

使用 app() 系统容器获取到 hash 操作的示例对象,对应的别称定义:

\config\app.php

'Hash' => Illuminate\Support\Facades\Hash::class,

门面定义里 @see \Illuminate\Hashing\BcryptHasher 指向,实际的实现类。

BcryptHasher 主要定义了 make()check() 两个方法,分别表示生成密码 hash 值和验证密码。查看内容发现,实现功能的基础依赖于 password_hash()password_verify()

// 获取密码 hash 值
$hash = password_hash($value, PASSWORD_BCRYPT, ['cost' => $cost]);
...
// 验证密码
password_verify($value, $hashedValue)

包括之前的注册、登录也是默认通过这样的一对函数进行加密、验证的。

password_hash() 函数在第二个参数为 PASSWORD_BCRYPT 时,第三个参数有两个关联参数,一个为 cost,默认 10 表示算法消耗,另一个为 salt,也就是常说的盐值。PHP 7.0 以后 salt 取消了,所以可以不用携带,让函数自动生成。

bcrypt