如何在NodeJs中使用Bcrypt来保护用户密码

发布于:2022-11-09 ⋅ 阅读:(14) ⋅ 点赞:(0) ⋅ 评论:(0)

        不管你给你的程序进行了多少加密,黑客都可能有一万种办法黑进你的数据库。一个成熟的软件必须要有额外的加密系统。这样,即使数据库真的被攻破,我们也可以更好地保护我们的用户信息。这就是Bcrypt的作用,加盐salt和散列hash

注意:本文仅仅讲解Bcrypt的作用及用法,因此会尽量少的设计额外的概念。在真正写码时所需要的数据库的操作以及路由的操作会尽量忽略

目录

为什么要给密码加密

在NodeJs中使用Bcrypt加密

在用户登录的时候使用Bcrypt校验身份


为什么要给密码加密?

        散列(hash)的意思是给一段普通文字使用算法加密,使他变成一个固定长度的字符串。不管这段文字有多长,经过算法处理后的最终的结果都将是相同长度。并且每次的结果都将完全相同。

        举个例子,不过你是把111还是把'alongword'或者是其他的一些文本传进去,结果都会是一样的长度。并且相同的字符会一定会产出相同的结果。这显然不是一个安全的做法。所以仅仅散列是不够的。

给密码加盐

        盐 (salt)是一个随机的字符串。如果你在hash的时候加入盐作为干扰的话,那么结果就不会再保持相同了。盐会被自动加到hash里面,所以你不需要刻意把他保存到数据库里面。

        Bcrypt早在1996年就存在,并且经过多年的大量网站的使用和验证,鲜有报道出来的问题。可以说他的这一套算法是很安全的。接下来,我们将使用node的中间件来让Bcrypt为我们的用户密码加盐并散列。


在NodeJs中使用Bcrypt加密

        首先,如果你不是很熟悉node,我们要先初始化一个node程序:

mkdir jwt-project 创建文件夹

cd jwt-project 进入文件夹

npm init -y 初始化node程序

        接下来,我们需要安装一些依赖:

npm install bcrypt

        安装完所需要的依赖后,我们就可以在node模块中引入并使用Bcrypt了

const bcrypt = require('bcrypt');

        接下来,我们需要一个变量:saltRounds。saltRounds 代表加密所需的时间,saltRounds越大,加密所需时间越长,加密后的密码也就越安全。但是我们也不想让用户永远等着我们加密密码,所以一般使用默认值10就可以。

const saltRounds = 10;

        为了方便,我们就不使用真实用户的密码了。我们自己写一个固定值就好

var password = "iamapassword";

        接下来,我们要利用Bcrypt的genSalt和hash方式来生成并且存储我们最终生成的hash。首先,我们先使用bcrypt.genSalt会接收saltRounds回调函数,这个回调函数会返回salt结果和error对象:

bcrypt.genSalt(saltRounds, function(err, salt) {
  // 返回salt值或者进行错误处理
});

         在得到salt值后,我们在回调的内部再调用Bcrypt的hash方式来生成hash。hash接受三个参数,分别是密码salt,和回调函数通常,我们会在这个回调函数里将处理好的hash存储到数据库中或者进行错误处理。

bcrypt.genSalt(saltRounds, function(err, salt) {

  bcrypt.hash(password, salt, function(err, hash) {

  // 返回hash的值,并将他存储到数据库中

  });

});

但其实,你也可以把以上两个函数合并成一个,结果如下

bcrypt.hash(password, saltRounds, function(err, hash) {
  // 数据库操作和错误处理
});

在用户登录的时候使用Bcrypt校验身份

        如果你知道如何查看数据库的话,你会发现这时候新注册的用户密码已经变成了一段长长的hash。这时候,再当用户登录的时候,我们就不能简单的对比用户输入的密码和数据库的hash了。Bcrypt为我们提供了一个方法,叫做compare。bcrypt.compare()会接受三个参数,分别是用户输入的密码数据库中的hash,和回调函数回调函数会返回一个布尔值,如果密码和hash吻合的话,就返回true,反之false。

         仍然为了方便起见,我们手写一个字符串充当密码,来让bcrypt帮我们验证密码是否正确

var password2 = "iamapassword";
bcrypt.compare(password2, hash, function(err, result) {
  if (result) {
    console.log("密码正确")
  }
  else {
    console.log("密码错误");
  }
});

总结:

        Bcrypt的存在为我们的程序多加了一层保障,它利用加盐和散列的算法将我们的密码加密成一段很难破解的长字符串,这样,即使我们的数据库被攻破,hash后的密码也可以给我们提供最后一层保护