我有一个要登录的脚本代码。
不幸的是,不再推荐使用sha1
。我尝试将其更改为password_hash()
,但失败了。
原始
public static function create($username, $password)
{
$q = self::$db->prepare('INSERT INTO user(username, password, email) VALUES (:username, :password, :email)');
return $q->execute(array(
':username' => $username,
':password' => sha1($password),
':email' => $email,
));
}
修改
public static function create($username, $password)
{
$q = self::$db->prepare('INSERT INTO user(username, password, email) VALUES (:username, :password, :email)');
$new_password = password_hash($password, PASSWORD_DEFAULT);
return $q->execute(array(
':username' => $username,
':password' => $new_password,
':email' => $email,
));
}
它出了什么问题?
答案 0 :(得分:3)
恭喜您改变远离古老而不安全的算法!!
我有一些关于如何在my answer to PHP Secure password generation and storage中使用password_hash的信息,但其实质内容复制如下:
特别是,您可以以足够高的成本对密码进行散列(选择的成本只需要在预期的最大负载下足够长,您的站点就不会受到CPU限制) - 例如在password_hash Example 2中,但是有了更新的工作因素:
<?php
/**
* In this case, we want to increase the default cost for BCRYPT to 12.
* Note that we also switched to BCRYPT, which will always be 60 characters.
*/
$options = [
'cost' => 14,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
?>
然后存储它返回的字符串,其中包括加密生成的随机盐和您设置的工作因子 - 根据高峰时间的登录率与CPU功率相比,尽可能多地增加工作因子,记住在峰值时,所有核心都可以并行工作,因为它们每个都可以为不同的用户进行散列!
要验证,检索从您存储它的任何地方(即您的数据库)返回的字符串,并与password_verify example进行比较:
<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
if (password_verify('rasmuslerdorf', $hash)) {
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
?>
与往常一样,如果您需要详细信息,请阅读Thomas Pornin's canonical answer to How to securely hash passwords - 但PHP 5.5密码功能使用Bcrypt,因此您可以使用足够高的费用。