当我尝试加密相同的密码时,bycrypt.js 加密的工作方式很奇怪

问题描述 投票:0回答:1

我正在用 Angular 和 Express 做一个项目。我注意到

bycrypt.js
的加密有些奇怪。假设有 2 个用户,分别称为“用户 1”和“用户 2”,他们的密码是“Password@1234”,所以他们是相同的。当我提交用户 1 的登录表单,然后对用户 2 执行同样的操作时,我注意到服务器端的加密有些非常奇怪:

User1
Register password: Password@1234
Encrypted above pwd: $2a$12$MMZrwIu0oheKkbzz1rOS2ul4JxXRRYTh3VU0R3ItzI9DTQ.FrGsWO
========================================================================================
User2
Register password: Password@1234
Encrypted above pwd: $2a$12$IAbbkcm5oGinBuyfLNnEJupuU6gJ65kLvrromT7Pb.YybyMcipege

现在,如您所见,密码(不是加密的密码)是相同的。但为什么加密方式不同呢?如果我尝试使用这两个用户之一使用相同的密码登录,它会在客户端加密,它会说密码错误。

这是代码:

正面

sign-up.component.ts

signUp(): void {
    if (this.signUpForm.valid) {
      const formData = this.signUpForm.value;
      this.httpClient.post('http://localhost:3000/sign-up', formData).subscribe(
        (response) => {
          const message = (response as SignUpResponse).message;
          this.appendAlert(message, "success", 1);
          this.signUpSuccess = true;
        },
        (error: HttpErrorResponse) => {
          this.appendAlert(error.message, "danger", 1)
        }
      );
    }
}

登录.component.ts

import * as bcrypt from 'bcryptjs';

export class LogInComponent{
  encryptPassword(password: string): string {
    const saltRounds = 12;
    const salt = bcrypt.genSaltSync(saltRounds);
    const hash = bcrypt.hashSync(password, salt);
    return hash;
  }
  logIn(): void {
    if (this.logInForm.valid) {
      const formData = this.logInForm.value;
      formData.userPwd = this.encryptPassword(formData.userPwd);
      this.httpClient.post('http://localhost:3000/log-in', formData).subscribe(
        (response) => {
          const message = (response as LogInResponse).message;
          this.appendAlert(message, "success", 1);
          this.logInSuccess = true;
        },
        (error: HttpErrorResponse) => {
          this.appendAlert(error.error.message, "danger", 1)
          if (error.error.message.includes('Account locked')) {
            this.logInForm.disable();
            setTimeout(() => this.logInForm.enable(), 300000); // 5 minutes
          }
        }
      );
    }
  }
}

服务器端

sign-up.js

"use strict"
const express = require('express');
const router = express.Router();
const connection = require('./db/connection');
const crypto = require('crypto');
const nodemailer = require('nodemailer');
const bcrypt = require('bcryptjs');


//Encrypt password method
function encryptPassword (password) {
    const saltRounds = 12;
    const salt = bcrypt.genSaltSync(saltRounds);
    const hash = bcrypt.hashSync(password, salt);
    return hash;
}

// Sign-up endpoint
router.post('/sign-up', (req, res) => {
    const { userName, userEmail, userContact, userDOB, userPwd} = req.body;
    if (!userName || !userEmail || !userContact || !userDOB || !userPwd ) {
        return res.status(400).json({ error: 'All fields are required' });
    }

    const encryptedPwd = encryptPassword(userPwd);
    const verificationPin = crypto.randomInt(100000, 1000000).toString();
    const isVerified = 0;

    console.log("Register password: "+userPwd);
    console.log("Encrypted above pwd: "+encryptedPwd);
    
    
    const sql = 'INSERT INTO users (name, email, contactNumber, dob, pwd, verificationPin, isVerified) VALUES (?, ?, ?, ?, ?, ?, ?)';
    const userValues = [userName, userEmail, userContact, userDOB, encryptedPwd, verificationPin, isVerified];

    connection.execute(sql, userValues, (err, _results) => {
        if (err) {
            console.error(err);
            return res.status(500).json({ error: 'Error while inserting data' });
        } else {
            sendEmail(userEmail, userName, verificationPin, (emailError) => {
                if (emailError) {
                    return res.status(500).json({ message: 'Something went wrong while sending email' });
                } else {
                    return res.status(200).json({ message: 'User has been created successfully! Now check your email to insert PIN below' });
                }
            });
        }
    });
});

module.exports = router;

登录.js

// Log-in endpoint
router.post('/log-in', (req, res) => {
    const { userName, userPwd } = req.body;
    const sql = 'SELECT * FROM users WHERE name = ?';

    connection.execute(sql, [userName], (err, results) => {
        if (err) {
            console.error('Error while logging: ', err);
            return res.status(500).json({ error: 'Oops! Something went wrong! Please try again later.' });
        } else {
            if (results.length === 0) {
                return res.status(400).json({ message: `Username doesn't exist! You may sign up or try again.` });
            } else {
                const user = results[0];
                console.log(results);
                const now = new Date();

                if (user.lock_until && now < new Date(user.lock_until)) {
                    return res.status(400).json({ message: `Account locked. Try again later. Account will be unlocked at ${user.lock_until}`});
                } else {
                    console.log("Entered pwd: "+userPwd);
                    console.log("Database pwd: "+user.pwd)
                    
                    if (bcrypt.compareSync(userPwd, user.pwd)) {
                        connection.execute('UPDATE users SET failed_attempts = 0, lock_until = NULL WHERE name = ?', [userName]);
                        return res.status(200).json({ message: 'You successfully logged in!' });
                    }
                     else {
                        let failedAttempts = user.failed_attempts + 1;
                        let lockUntil = null;

                        if (failedAttempts >= 5) {
                            lockUntil = new Date(now.getTime() + 5 * 60000); // 5 minutes lock
                        }

                        connection.execute('UPDATE users SET failed_attempts = ?, lock_until = ? WHERE name = ?', [failedAttempts, lockUntil, userName]);
                        return res.status(400).json({ message: `Password doesn't match! ${5 - failedAttempts} attempts remaining!` });
                    }
                }
            }
        }
    });
});

如何确保加密后的密码相同?

如有任何帮助,我们将不胜感激!

angular express password-encryption
1个回答
0
投票

特别感谢@hoangdv。感谢他,我意识到我错误地使用了

bcrypt.compareSync()
:因为该方法的前两个参数是非加密密码和加密密码。相反,我将我在客户端加密的密码作为参数插入,然后插入数据库密码。

所以,正如@hoangdv所说,我应该在客户端删除

formData.userPwd = this.encryptPassword(formData.userPwd);
。它成功了!

© www.soinside.com 2019 - 2024. All rights reserved.