password_verify 验证密码是否和散列值匹配

最近看到一篇文章是说当前大部分web应用在保存用户密码时都是用的hash加密。比如单纯的使用md5对用户密码进行加密,然后就存在数据库里,这样做对于不了解计算机的人来说确实可以,但是现在网络越来越发达,网上已经出现了不少专门对md5解密(加密)的网站,试的用户的密码信息更容易被破解和攻击。

文档中提到在当下,最好的密码哈希选项是 bcrypt,这是专门为哈希密码而设计的哈希算法,同时这套哈希算法里还允许你配置一些参数来加大破解的难度。

新版的 PHP 中自带了安全的密码哈希函数password_hash,此函数已经包含了加盐处理。对应的密码验证函数为 password_verify用来检测密码是否正确。password_verify 还可有效防止时序攻击。

以下就是我自己在本地做的测试。

 

1.password_hash 创建密码的散列(hash),此函数要求php版本:PHP 5 >= 5.5.0, PHP 7

password_hash ( string $password , mixed $algo [, array $options ] ) : string

password_hash() 使用足够强度的单向散列算法创建密码的散列(hash),

返回散列后的密码, 或者在失败时返回 FALSE

使用的算法、cost 和盐值作为散列的一部分返回。所以验证散列值的所有信息都已经包含在内。 这使 password_verify() 函数验证的时候,不需要额外储存盐值或者算法的信息。

需要澄清的一点是:密码哈希并不是密码加密。哈希(Hash)是将目标文本转换成具有相同长度的、不可逆的杂凑字符串(或叫做消息摘要),而加密(Encrypt)是将目标文本转换成具有不同长度的、可逆的密文。显然他们之间最大的区别是可逆性,在储存密码时,我们要的就是哈希这种不可逆的属性。

2.password_hash()示例

$password = 'ceshi123456';
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);//返回长度为60的散列,且每次刷新会生成新的字符串
echo strlen($hashedPassword) . "<br>";
echo $hashedPassword;

3.password_verify  验证密码是否和散列值匹配,此函数要求php版本:PHP 5 >= 5.5.0, PHP 7

password_verify ( string $password , string $hash ) : bool

验证密码是否和指定的散列值匹配。

注意 password_hash() 返回的散列包含了算法、 cost 和盐值。 因此,所有需要的信息都包含内。使得验证函数不需要储存额外盐值等信息即可验证哈希。

时序攻击(timing attacks)对此函数不起作用。

4.password_verify ()示例

//用户通过前端输入的密码
$userPassword = 'ceshi123456';

$password = 'ceshi123456';
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);//password_hash生成的hash密码

if(password_verify($userPassword, $hashedPassword)) {
  echo 'Password Sucess!';
} else {
  echo 'Password Faild.';
}

5.password_get_info 返回指定散列(hash)的相关信息

如果传入的散列值(hash)是由 password_hash() 支持的算法生成的, 这个函数就会返回关于此散列的信息数组。

$password = 'ceshi123456';
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);//password_hash生成的hash密码
print_r(password_get_info($hashedPassword));

6.password_needs_rehash 检测散列值是否匹配指定的选项

此函数检测指定的散列值是否实现了提供的算法和选项。 如果没有,需要重新生成散列值。

$password = 'ceshi123456';
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);//password_hash生成的hash密码
// $options = array('cost' => 10);
$options = array('cost' => 11);//默认为10
if(password_needs_rehash($hashedPassword, PASSWORD_DEFAULT, $options)){
    $newHashPassword = password_hash($password, PASSWORD_DEFAULT,$options);
    echo $newHashPassword;
}else{
    echo 'Ok';
}

 

7.参考文档:

password_hash

password_verify 

password_get_info

password_needs_rehash

 

 

 

 

posted @ 2020-09-28 15:17  流浪2024  阅读(1172)  评论(0编辑  收藏  举报