创建密码哈希

使用 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 选项已被弃用 。现在优选简单地使用默认生成的盐。