【问题标题】:PHP password_hash always contains hashkeyPHP password_hash 总是包含 hashkey
【发布时间】:2014-01-04 14:40:36
【问题描述】:

我正在尝试为此测试 password_hash 方法,我创建了以下函数 hashPassword

function hashPassword($string) {
    $settings = array('cost' => 10, 'encryption_key' => 'thisIsMyEncryptionKey1234');
    return password_hash($string, PASSWORD_BCRYPT, $settings);
}

现在如果我用像"test"这样的随机字符串来测试它

结果是:

$2y$10$thisIsMyEncryptionKeyu5n3NNnKh3DjgJqgb5pE8YOLBclKrVWC

或者如果我用helloworld 测试它:

$2y$10$thisIsMyEncryptionKeyuVw8QRVNw8HbEWHX2oQlArVtne2TzOpS

谁能告诉我为什么会这样?还是应该是这样的?

【问题讨论】:

  • 加密密钥应该是随机生成的
  • 什么?如何验证用户密码是否正确???
  • $options 数组中传递'encryption_key' 绝对没有任何作用。我想你的意思是'salt'
  • 是的。只有 2 个受支持的选项,盐和成本。

标签: php password-encryption php-password-hash


【解决方案1】:

除非您有充分的理由,否则切勿手动提供加密密钥。 I'd recommend reading the docs on password_hash some more.

正确使用只会让系统自行解决所有问题:

function hashPassword($password)
{
    return password_hash($password, PASSWORD_DEFAULT);
}

然后,PHP 将在内部为当前硬件选择最佳可用算法和最合适的迭代次数,并生成安全且唯一的盐。

要验证密码,然后使用password_verify,并检查所需的重新哈希,例如在User 类中:

class User
{
    ...

    public function verifyPassword($password)
    {
      if(!password_verify($password, $this->hash))
        return false;
      if(password_needs_rehash($this->hash, PASSWORD_DEFAULT))
        $this->setNewHashAndSaveToDB(password_hash($password, PASSWORD_DEFAULT));
      return true;
    }
}

通过使用这种结构,您可以确保散列密码始终保持最新并且随着硬件容量的提高而安全,在用户登录时自动进行。

PASSWORD_DEFAULT选择什么算法,使用什么配置的策略如下:

通过此函数更新支持的算法(或更改 默认一)必须遵循以下规则:

  • 在成为默认算法之前,任何新算法都必须成为 PHP 至少 1 个完整版本的核心。因此,例如,如果一个新算法 在 5.5.5 中添加,直到 5.7 才符合默认条件 (自从 5.6 将是第一个完整版本)。但是,如果在 5.6.0 中添加了不同的算法,它也可以在 5.7.0 中默认使用。
  • 默认值仅应在完整版本(5.6.0、6.0.0 等)上更改,而不应在修订版本上更改。唯一的例外是 在紧急情况下,当发现一个严重的安全漏洞时 当前默认值。

【讨论】:

  • 比如说你创建了一个登录系统,你将用户密码保存在数据库中?然后如何验证用户输入的密码?
  • 添加了所有内容。 It's all in the docs though.
  • 这是否会使在数据库中保存散列密码无用?
  • 如果哈希值与当前密码返回的哈希值相同,我不明白 verifyPassword 将如何验证任何内容而不检查数据库是否匹配。永远不会因为哈希键是随机的?
  • $this->hash 是您可以/将如何将其存储在 User 类中的方式,并且是您存储在数据库中的哈希字符串。拜托,这真的都解释了extremely well on the PHP site
【解决方案2】:

About加密密钥:

最佳加密密钥是从可靠的随机数生成器生成的二进制 blob。建议使用以下示例 (>= 5.3):

$keySize = mcrypt_get_key_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CFB);
$encryptionKey = openssl_random_pseudo_bytes($key_size, $strong); //$strong will be true if the key is crypto safe

但在您的情况下,您只需设置字符串,为此使用一些随机数据。

【讨论】:

  • 实际上 OP 是在谈论盐,而不是加密密钥。 BCrypt 的盐应该有 22 个字符,并且必须满足某些条件(仅限给定字母表的字符)。最好让password_hash()自己生成盐。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-09
  • 1970-01-01
  • 1970-01-01
  • 2019-04-25
  • 1970-01-01
  • 2019-01-13
  • 2018-12-02
相关资源
最近更新 更多