PHP官方自带的密码哈希函数password_hash

常用的MD5、SHA1、SHA256哈希算法,是面向快速、高效进行哈希处理而设计的。随着技术进步和计算机硬件的提升,如今强大的计算机很容易破解这种算法。也就是说,不要用MD5、SHA1、SHA256这种哈希方法加密密码了,不太安全。
还好,PHP内置了密码哈希函数password_hash,使用这个方法,PHP会升级底层的算法,达到如今的安全标准水平。

版本要求:

PHP 5 >= 5.5.0, PHP 7

password_hash使用方法

string password_hash ( string $password , int $algo [, array $options ] )
参数:

password: 用户的密码
algo:密码算法常量,建议使用PASSWORD_DEFAULT
options:一个包含有选项的关联数组,目前支持两个选项:salt(从 PHP 7.0.0 开始被废弃),在散列密码时加的盐(干扰字符串),以及cost,用来指明算法递归的层数(默认10)。

<?php
/**
 * 我们想要使用默认算法散列密码
 * 当前是 BCRYPT,并会产生 60 个字符的结果。
 *
 * 请注意,随时间推移,默认算法可能会有变化,
 * 所以需要储存的空间能够超过 60 字(255字不错)
 */
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
?>

验证密码

由于使用的随机salt,每次加密后的密码都是不一样的,不能用普通==来判断密码是否相等,因此php提供了相应的函数来验证password_verify

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

password:用户的密码。
hash:一个由 password_hash() 创建的散列值。

<?php
// 想知道以下字符从哪里来,可参见 password_hash() 的例子
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
 
if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>

检测存储的密码是否匹配

检测存储的密码是否与您指定的当前安全需求相匹配。如果不匹配,原因可能是,您增加了 cost 参数,或者一个新的 PHP 版本在幕后更改为一种不同的哈希算法。正因如此,PASSWORD_DEFAULT 应当是您首选的算法;此选项始终会使您的软件使用当前的最佳实践版本。

说明:
bool password_needs_rehash ( string $hash , int $algo [, array $options ] )

hash: 一个由 password_hash() 创建的散列值。
algo: 一个用来在散列密码时指示算法的密码算法常量。
options: 一个包含有选项的关联数组。目前支持两个选项:salt(从 PHP 7.0.0 开始被废弃),在散列密码时加的盐(干扰字符串),以及cost,用来指明算法递归的层数(默认10)。

例子:
 
<?php
 
$password = 'rasmuslerdorf';
$hash = '$2y$10$YCFsG6elYca568hBi2pZ0.3LDL5wjgxct1N8w/oLR/jfHsiQwCqTS';
 
// 当硬件性能得到改善时,cost 参数可以再修改
$options = array('cost' => 11);
 
// 根据明文密码验证储存的散列
if (password_verify($password, $hash)) {
    // 检测是否有更新的可用散列算法
    // 或者 cost 发生变化
    if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options)) {
        // 如果是这样,则创建新散列,替换旧散列
        $newHash = password_hash($password, PASSWORD_DEFAULT, $options);
    }
 
    // 使用户登录
}
?>

参考内容
php官方文档 http://php.net/manual/zh/book.password.php

Leave a Reply

Your email address will not be published. Required fields are marked *