时间:2021-07-01 10:21:17 帮助过:84人阅读
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
laravel 5.2 默认的密码加密,怎么加点盐?
顺便弱弱的问一下:盐是啥?
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
bcrypt生成的密码hash中已经包含盐了
盐是用于防止从彩虹表中反查出密码的随机字符串
没有盐的情况: 用户密码是123456, 傻程序员就直接在数据库保存hash('123456'), 坏人拿到数据库后就可以直接从这个hash反查出密码
有盐的情况: 用户仍然用123456, 正常程序员在数据库保存hash('123456'+盐)和盐. 坏人拿到数据库后很难从这个hash还原出密码 (暴力破解仍然可能, 但是至少把低成本的彩虹表废掉了)
https://github.com/laravel/framework/blob/5.1/src/Illuminate/Hashing/BcryptHasher.php
查看这部分的源代码可得,
// Laravel 的 bcrypt 就是
$hash = password_hash($value, PASSWORD_BCRYPT, ['cost' => 10]);
因为 password_hash 使用的是 crypt 算法, 因此参与计算 hash值的:
算法(就像身份证开头能知道省份一样, 由盐值的格式决定), cost(默认10) 和 盐值 是在$hash中可以直接看出来的!
所以说, Laravel 中bcrypt的盐值是PHP自动随机生成的字符, 虽然同一个密码每次计算的hash不一样.
但是通过 $hash 和 密码, 却可以验证密码的正确性!
具体来说, 比如这个
$hash = password_hash('password',PASSWORD_BCRYPT,['cost' => 10]);
echo $hash;
// 比如我这次算的是
// $hash = '$2y$10$DyAJOutGjURG9xyKgAaCtOm4K1yezvgNkxHf6PhuLYBCENk61bePm';
那么我们从这个 crypt的hash值中可以看到,
因为以$2y$开头, 所以它的算法是 CRYPT_BLOWFISH .
同时 CRYPT_BLOWFISH 算法盐值格式规定是 :
以$2y$开头 + 一个两位cost参数 + $ + 22位随机字符("./0-9A-Za-z")
$hash(CRYPT_BLOWFISH是固定60位) = 盐值 + 31位单向加密后的值
参见: https://secure.php.com/manual/en/function.crypt.php
验证密码
if (password_verify('password', $hash)) {
echo '密码正确.';
} else {
echo '密码错误!';
}
// 原理是:
if ($hash === crypt('password', '$2y$10$DyAJOutGjURG9xyKgAaCtO')) {
echo '密码正确.';
} else {
echo '密码错误!';
}
如果自己写用户系统并且使用PHP5.5+或PHP7,可以考虑使用PHP自带的password_hash()和password_verify(),非常方便