用户注册时,如果不对密码做一些加密处理直接明文存储到数据库中,一旦数据库泄露,对用户和公司来说,都是非常严重的问题。
MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。 通常将128位MD5哈希表示为32位十六进制值。
$ npm install js-md5
const md5 = require('js-md5')
md5('123456') // e10adc3949ba59abbe56e057f20f883e
理论上是不能破解的,因为md5采用的是不可逆算法。
有的网站上提供MD5解密,是因为有大量的存储空间来保存源码和加密后的密码,当解密时就是一个查询的过程,稍微复杂点的查询就无法完成。
这种解密方式,叫做 字典攻击
解决 字典攻击 的方式是 加盐。
bcryptjs 是 nodejs 中比较出色的一款处理加盐加密的包。
所谓加盐,就是在加密的基础上再加点“佐料”。这个“佐料”是系统随机生成的一个随机值,并且以随机的方式混在加密之后的密码中。
由于“佐料”是系统随机生成的,相同的原始密码在加入“佐料”之后,都会生成不同的字符串。
这样就大大的增加了破解的难度。
如果加盐还不行,还可以再来点味精、鸡精、生姜、胡椒.....
$ npm install bcryptjs
// 引入 bcryptjs
const bcryptjs = require('bcryptjs')
// 原始密码
const password = '123456'
/**
* 加密处理 - 同步方法
* bcryptjs.hashSync(data, salt)
* - data 要加密的数据
* - slat 用于哈希密码的盐。如果指定为数字,则将使用指定的轮数生成盐并将其使用。推荐 10
*/
const hashPassword = bcryptjs.hashSync(password, 10)
/**
* 输出
* 注意:每次调用输出都会不一样
*/
console.log(hashPassword) // $2a$10$P8x85FYSpm8xYTLKL/52R.6MhKtCwmiICN2A7tqLDh6rDEsrHtV1W
/**
* 校验 - 使用同步方法
* bcryptjs.compareSync(data, encrypted)
* - data 要比较的数据, 使用登录时传递过来的密码
* - encrypted 要比较的数据, 使用从数据库中查询出来的加密过的密码
*/
const isOk = bcryptjs.compareSync(password, '$2a$10$P8x85FYSpm8xYTLKL/52R.6MhKtCwmiICN2A7tqLDh6rDEsrHtV1W')
console.log(isOk)
这里面有个问题:在bcrypt.compareSync,为什么没有参数salt?由于哈希是从salt生成的,为什么比较明文密码不涉及哈希中使用的原始盐?
虽然对同一个密码,每次生成的hash不一样,但是hash中包含了salt(hash产生过程:先随机生成salt,salt跟password进行hash); 在下次校验时,从hash中取出salt,salt跟password进行hash;得到的结果跟保存在DB中的hash进行比对,compareSync中已经实现了这一过程:bcrypt.compareSync(password, hashFromDB);
再看代码:
const bcryptjs = require('bcryptjs')
// 原始密码
const password = '123456'
/**
* 加密处理 - 同步方法
* bcryptjs.hashSync(data, salt)
* - data 要加密的数据
* - slat 用于哈希密码的盐。如果指定为数字,则将使用指定的轮数生成盐并将其使用。推荐 10
*/
const hashPassword = ()=>bcryptjs.hashSync(password, 8);
console.log(hashPassword())
console.log(hashPassword())
console.log(hashPassword())
console.log(hashPassword())
console.log(hashPassword())
console.log(hashPassword())
console.log(hashPassword())
代码中,我们加了8这个盐,连续多次生成密码,看一下打印结果:
我们看到,生成的密码中保存了盐,而每次验证时,会将盐取出来。
The bcrypt
standard makes storing salts easy - everything it needs to check a password is stored in the output string.
The prefix "$2a$" or "2y" in a hash string in a shadow password file indicates that hash string is a bcrypt hash in modular crypt format. The rest of the hash string includes the cost parameter, a 128-bit salt (base-64 encoded as 22 characters), and the 192-bit[dubious – discuss] hash value (base-64 encoded as 31 characters).
以上便是使用bcryptjs加密的方法,希望对你有所帮助。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。