创建密码哈希
使用 password_hash()
创建密码哈希以使用当前行业最佳实践标准哈希或密钥派生。在撰写本文时,标准是 bcrypt ,这意味着,PASSWORD_DEFAULT
包含与 PASSWORD_BCRYPT
相同的值。
$options = [
'cost' => 12,
];
$hashedPassword = password_hash($plaintextPassword, PASSWORD_DEFAULT, $options);
第三个参数不是强制性的。
应根据生产服务器的硬件选择'cost'
值。增加它会使密码生成成本更高。它产生的成本越高,任何人都试图破解它以产生它的时间越长。理想情况下,成本应该尽可能高,但实际上应该设置成本,这样就不会减慢太多的速度。介于 0.1 到 0.4 秒之间就可以了。如果你有疑问,请使用默认值。
Version < 5.5
在低于 5.5.0 的 PHP 上,password_*
功能不可用。你应该使用兼容包来替换这些功能。请注意,兼容包需要 PHP 5.3.7 或更高版本,或者将 $2y
修复程序反向移植到其中的版本(例如 RedHat 提供)。
如果你不能使用它们,你可以用 crypt()
实现密码散列。由于 password_hash()
是作为 crypt()
函数的包装器实现的,你不需要丢失任何功能。
// this is a simple implementation of a bcrypt hash otherwise compatible
// with `password_hash()`
// not guaranteed to maintain the same cryptographic strength of the full `password_hash()`
// implementation
// if `CRYPT_BLOWFISH` is 1, that means bcrypt (which uses blowfish) is available
// on your system
if (CRYPT_BLOWFISH == 1) {
$salt = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
$salt = base64_encode($salt);
// crypt uses a modified base64 variant
$source = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
$dest = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$salt = strtr(rtrim($salt, '='), $source, $dest);
$salt = substr($salt, 0, 22);
// `crypt()` determines which hashing algorithm to use by the form of the salt string
// that is passed in
$hashedPassword = crypt($plaintextPassword, '$2y$10$'.$salt.'$');
}
Salt 用于密码哈希
尽管 crypt 算法具有可靠性,但仍然存在针对彩虹表的漏洞。这就是为什么建议使用盐的原因。
salt 是在散列之前附加到密码以使源字符串唯一的东西。给定两个相同的密码,产生的哈希值也是唯一的,因为它们的盐是独特的。
随机盐是密码安全性中最重要的部分之一。这意味着即使使用已知密码哈希的查找表,攻击者也无法将用户的密码哈希与数据库密码哈希匹配,因为已使用随机盐。你应该始终使用随机和加密安全的盐。阅读更多
使用 password_hash()
bcrypt
算法,纯文本 salt 与生成的哈希一起存储,这意味着哈希可以跨不同的系统和平台传输,并且仍然可以与原始密码进行匹配。
Version < 7
即使不鼓励这样做,也可以使用 salt
选项定义自己的随机盐。
$options = [
'salt' => $salt, //see example below
];
重要的。如果省略此选项,则每个密码哈希值将由 password_hash()
生成随机盐。这是预期的操作模式。
Version >= 7
自 PHP 7.0.0 起,salt 选项已被弃用 。现在优选简单地使用默认生成的盐。