PHP 已经拥有您需要的散列函数。我更喜欢使用hash_pbkdf2(),但它仅在 PHP 的后期版本中可用。所以我经常使用标准化程度较低的crypt()函数。
它们的工作方式基本相同:您获取密码、算法和一些盐,然后将密码散列多次(数千次)。输出哈希包括进入其中的额外参数(算法、盐和轮数),因此您可以在有人尝试登录时重新创建哈希。
这两种技术的优点是:
- 您可以选择散列算法
- 添加随机盐使字典攻击更加困难
- 额外的散列轮次使蛮力攻击变得更加困难。
我写了一个简短的例子,带有一点单元测试。
/* Hashes a password using 2000 rounds of SHA-256 and a random salt.
Returns a string.
*/
function hashpw($password) {
$algo = '$5$rounds=2000$'; // specify SHA-256
$salt = $algo . mt_rand();
return crypt(strval($password), $salt);
}
/* Given a password and a hash produced by hashpw(), tells you if the hash
belongs to the password or not.
Returns a boolean.
*/
function confirmpw($password, $hash) {
return (crypt(strval($password), strval($hash)) === $hash);
}
$passwords = array(
'hello world',
'secret',
'super-secret',
'my pets name',
);
foreach($passwords as $onePass) {
$hash = hashpw($onePass);
$verified = confirmpw($onePass, $hash) ? 'verified' : 'failed' ;
echo "$onePass ==> $hash ==> $verified \n";
}