简体   繁体   English

Bcrypt密码与mysql和nodejs比较

[英]Bcrypt password compare with mysql and nodejs

I am not very experienced in programming and I came into this problem.我在编程方面不是很有经验,我遇到了这个问题。

I am trying to create some security and when I create a user inside the database the encryption takes place.我正在尝试创建一些安全性,当我在数据库中创建用户时,就会发生加密。 For the purpose of this project I have some normal passwords inside the database ( not encrypted ) and some hashed password ( the one from registration ) When I try to authenticate the user I came across an issue.出于该项目的目的,我在数据库中有一些普通密码(未加密)和一些散列密码(来自注册的密码)当我尝试对用户进行身份验证时遇到了一个问题。 With match = await bcrypt.compare(password,result[0].password) I am only able to compare the hashed password to authenticate the user.使用match = await bcrypt.compare(password,result[0].password)我只能比较散列密码来验证用户身份。 But for the password that are not hashed is not possible to compare them.但是对于没有经过哈希处理的密码是不可能进行比较的。 How is the best aproach to solve this issue?解决这个问题的最佳方法是什么?

loginRouter.post("/register", (req, res) => {
  // register users with bcrypt password encryption
  bcrypt.hash(req.body.password, saltRounds, (err, hashedPassword) => {
    const { username, password } = req.body;
    const sql = `INSERT INTO acc_users (username, password) VALUES ('${username}', '${hashedPassword}')`;
    db.query(sql, (err, rows, fields) => {
      if (!err) {
        res.render("index");
      } else {
        console.log(err.message);
        res.send(err);
      }
    });
  });
});
loginRouter.post("/login",  (req, res) => {
  const user = req.body.username;
  const password = req.body.password;
  const sqlSearch = "SELECT * from acc_users WHERE username = ?";
  const search_query = db.format(sqlSearch, [user]);
  db.query(search_query, async (err, result) => {
    if (err) throw err;
    if (result.length == 0) {
    } else {
      //get the hashedPassword from result
      const userPasw = result[0].password;
      console.log(userPasw);
      bcrypt.compare(password, user).then(function (result) {
        // result == true
        console.log(result);
      });
      match = await bcrypt.compare(password,userPasw)
      // console.log(match)
      // MATCH only works with hasshed passwords
      // if (password === userPasw)
      if (match) {
        console.log(result);
        console.log("---------> Login Successful");
        console.log(password);
        req.session.loggedin = true;
        req.session.username = user;
        res.send(`${user} is logged in!`);
      } else {
        console.log("---------> Password Incorrect");
        res.send("Password incorrect!");
      }
    }
  });
});

For the purpose of this project I have some normal passwords inside the database ( not encrypted ) and some hashed password ( the one from registration )出于这个项目的目的,我在数据库中有一些普通密码(未加密)和一些散列密码(来自注册的密码)

There are a few approaches you can take here.您可以在这里采取一些方法。

The insecure approach不安全的方法

Do a basic comparison of the password as well as a hash comparison.对密码进行基本比较以及 hash 比较。

if (userPasw === password) {
    req.session.loggedin = true;
    // etc
} else {
    // Your existing logic starting with bcrypt.compare(password, user) here
}

The middleground中间地带

Loop through any row in the database with an unhashed password and run that passwork through your hashing algorithm.使用未散列的密码遍历数据库中的任何行,并通过散列算法运行该密码。 Then update the database with the result.然后用结果更新数据库。

The secure approach安全的方法

Require any account using an unhashed password to set a new password.要求使用未散列密码的任何帐户设置新密码。

Typically you'll do this through a normal password reset flow (such as sending a one time token to the user's email account that they can use to access a page that allows them to set a new password).通常,您将通过正常的密码重置流程来执行此操作(例如向用户的 email 帐户发送一次性令牌,他们可以使用该令牌访问允许他们设置新密码的页面)。


To do either of the last two options well you'll need to know which passwords were hashed and which were not.要做好最后两个选项中的任何一个,您需要知道哪些密码被散列,哪些没有。

If you don't have that information, then you can:如果您没有该信息,那么您可以:

  • Tell people who have failed login attempts that you have upgraded your password security and, as a consequence, accounts with passwords set before you did that need to reset them.告诉登录尝试失败的人您已经升级了密码安全性,因此,在您这样做之前设置了密码的帐户需要重置它们。
  • Force everybody to reset their passwords强制所有人重置密码

As @Lelio Feieta says, it is best to have all passwords in the database encrypted, even for security.正如@Lelio Feieta 所说,最好对数据库中的所有密码进行加密,即使是为了安全也是如此。 That way, it is possible when you already have the password in the database, it is already encrypted and you can compare them easier, without having to pass them from one format to another.这样,当您已经在数据库中拥有密码时,它是可能的,它已经被加密,您可以更容易地比较它们,而不必将它们从一种格式传递到另一种格式。

The only way I think to compare two password hashes is to know the plaintext beforehand and then apply the algorithm.我认为比较两个密码哈希的唯一方法是事先知道明文,然后应用算法。

Ex: This is how the password would be stored in the database.例如:这就是密码在数据库中的存储方式。

const myPlaintextPassword = 'testpassword'.
bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
  // Here you store in the database
  // Ex: hash = $2a$10$fKAyjaG0pCkisZfRpKsBxursD6QigXQpm1TaPBDZ4KhIZRguYPKHe
});

And to compare并进行比较

bcrypt.compare(myPlaintextPassword, hash, function(err, res) {
  // You compare with the user's password already stored in the database.
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM