加密算法
MD5
MD5是一种被广泛使用的密码散列函数,不可逆(法从密文推出原文),但是HASH 算法最大的问题是,会发生撞库,也就是说,有可能出现多个原文得到同一个密码。
一种攻击方法是,攻击者记录了一张巨大的密码库,预先计算了常用密码的 hash 值,这样只需要搜索 hash 值就能寻找到一个合适的密码用于登录。这就是被彩虹表攻击。
解决彩虹表的问题是加盐,在加密之前,对原文混入其他信息,混入的信息不存放到数据库中。实际寻找到其他原文也无法登录。
用法
导入
let md5 = require('md5');
生成一个MD5密码,这个密码是固定的,所以安全性不如 bcrypt
console.log(md5('123456')) //e10adc3949ba59abbe56e057f20f883e
密码验证
md5('123456') == e10adc3949ba59abbe56e057f20f883e //true
md5('123456789') == e10adc3949ba59abbe56e057f20f883e //false
Bcrypt
Bcrypt 有两个特点
1.每一次 HASH 出来的值不一样,安全性好
2.计算非常缓慢
因此使用 Bcrypt 进行加密后,攻击者想要使用算出 M2 成本变得不可接受。但代价是应用自身也会性能受到影响,不过登录行为并不是随时在发生,因此能够忍受。对于攻击者来说,需要不断计算,让攻击变得不太可能。
因此推荐使用 Bcrypt 进行密码加密
用法
导入
let bcrypt = require('bcryptjs')
生成一个hash密码,这个密码每次生成是随机的,所以安全问题比 MD5
更强一些
console.log(bcrypt.genSaltSync(10)); //$2a$10$TQdkC0XkrEEvm27OTQ7jwu
将原来的密码转换为hash密码
const hash = bcrypt.hashSync("123456", 10); //$2a$10$c7ggfPYaSpc..H9IfnXcQeOKt0kcr.CvwS2VSpBmApH2tvZC5u7qC
还有一种写法作为了解
const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync("123456", salt);
密码验证
bcrypt.compareSync("123456", hash); // true
bcrypt.compareSync("123456789", hash); // false
Demo
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./Ajax.js"></script>
<title>Document</title>
</head>
<body>
账号:<input type="text" class="user"><br>
密码:<input type="password" class="password"><br>
<button>登录</button>
<p></p>
<script>
let user = document.querySelector('.user')
let password = document.querySelector('.password')
let p = document.querySelector('p')
document.querySelector('button').onclick = function () {
Ajax('POST', url + '/users/login', {
username: user.value, //账号
password: password.value //密码
}).then(function (res) {
if (res.status !== 200) {
alert('登录失败!')
p.innerHTML = ''
return
}
alert('登录成功!')
p.innerHTML = '欢迎:admin 登录成功!'
})
}
</script>
</body>
</html>
MD5
代码实现
var express = require('express');
var query = require('../db/query');
let md5 = require('md5');
var router = express.Router();
// 用户注册
router.post('/register', async function (req, res) {
let { username, password, phone } = req.body;
if (!username || !password || !phone) {
res.send({
status: 100,
message: '注册失败!'
})
return;
}
// 将用户输入的密码转换为MD5
password = md5(password);
let sql = `insert into users(username,password,phone) values('${username}','${password}','${phone}')`;
let resule = await query(sql);
if (resule.affectedRows == 1) {
res.send({
status: 200,
message: '注册成功!'
})
}
})
// 用户登录
router.post('/login', async function (req, res) {
let { username, password } = req.body;
let sql = `select * from users where username='${username}'`;
let data = await query(sql);
// 将用户密码转换为MD5跟数据库中加密后的MD5密码进行比较
let md5BL = md5(password) == data[0].password;
if (md5BL) {
res.send({
status: 200,
message: '登录成功!'
})
return
}
res.send({
status: 100,
message: '登录失败'
})
})
module.exports = router;
Bcrypt
代码实现
var express = require('express');
var query = require('../db/query');
let bcrypt = require('bcryptjs')
var router = express.Router();
// 用户注册
router.post('/register', async function (req, res) {
let { username, password, phone } = req.body;
// 只要有一个值为空,就返回登陆失败
if (!username || !password || !phone) {
res.send({
status: 400,
message: '登陆失败!'
})
}
// 生成一个加密后的密码
password = bcrypt.hashSync(password, 10)
// 添加数据
let sql = `insert into users(username,password,phone) values('${username}','${password}','${phone}')`;
const result = await query(sql);
if (result.affectedRows == 1) {
res.send({
status: 200,
message: '注册成功!'
})
}
})
// 用户登陆
router.post('/login', async function (req, res) {
let { username, password } = req.body;
// 查询数据库中有没有对应的信息,会返回一个查到的信息
// let sql = `select * from users where username='${username}' && password='${password}'`;
let sql = `select * from users where username='${username}'`;
let data = await query(sql);
// 判断加密后的密码是否相等
const bcryptBL = bcrypt.compareSync(password, data[0].password)
// 如果没有查到登陆的信息,就登陆失败
if (!bcryptBL) {
res.send({
status: 400,
message: '登陆失败!'
})
} else {
// 查到信息了就登陆成功
res.send({
status: 200,
message: '登陆成功!'
})
}
})
// 查询用户
router.get('/get', async function (req, res) {
let sql = `select * from users`;
let data = await query(sql);
res.send({
status: 200,
data
})
})
module.exports = router;
链接: http://www.bylemon.cn
描述: 嘿,我在这~
头像: http://www.bylemon.cn/favicon.ico已经添加贵站,望互关~