在数据库中散列密码有什么意义?

What is the point of hashing passwords in the database?

我注意到大多数 api 教程都说您应该在发送前加密密码。它还显示了如何解密它们。我能做到,他们不也能做到吗?

这是来自 medium

的示例
UserSchema.pre('save', function (next) {
  var user = this;
  bcrypt.hash(user.password, 10, function (err, hash){
    if (err) {
      return next(err);
    }
    user.password = hash;
    next();
  })
});

他们说在这里散列它

bcrypt.compare(password, user.password, function (err, result) 

在这里,他们会在用户尝试登录时取消哈希。让我感到困惑的是,如果他们能够如此轻松地对其进行 unhash,那么攻击者也不能对其进行 unhash 吗?有人可以给我解释一下吗?

需要注意的是,尽管我已经编写了用户帐户系统并使用了安全哈希函数,但我不是任何类型的 "expert",但是对于那些想知道您是否真的遇到过这个问题的人必须经历使用安全哈希存储密码的麻烦:是的,你做到了。

此外,如果您仍然不确定,并且您对这些哈希方法的工作原理以及它们如何支持安全模型的理解不太满意,那么无论您是谁,您都应该坦诚相待重新工作是因为做担保权很难,需要经验和知识渊博的同行的审查。

无论如何,如评论中所述,为密码存储设计的安全哈希(如 bcryptscrypt)具有处理所有混乱工作的 API。我对 scrypt 更熟悉,但它们很相似。散列密码看起来像一串随机字符,但在字符串的开头是包含随机盐和散列参数的两个独立部分。

因为用于密码存储的安全散列总是将任意长度的密码散列并组成固定大小的散列字符串,没有充分的理由将用户密码限制为任意长度(除了像 1000 个字符这样的长度)用于避免 DOS 攻击)。

在数据库中散列密码有什么意义?

它限制了数据库泄露的潜在后果,因为攻击者不会获得明文密码。这非常重要,因为用户经常重复使用密码。

如果我能做到,他们就不能做到吗?

bcrypt 是一种单向密码。一旦对明文进行编码,您就无法取回它。

当您检查用户密码时,您是在检查用户输入的编码结果是否与存储的密码哈希匹配。

这意味着即使攻击者获得了盐和哈希值,他们仍然需要猜测密码。 Bcrypt 有一个内置的成本(缓慢),这使得测试彩虹 table 可能的密码非常昂贵。