0x0 前言
散列是给键值经过数学算法转换另外一个键值,在转换过程中是利用哈希函数生成,输出的内容无法还原,这边主要用于密码存储在数据需要进行散列处理。
加密是对信息编码,将原始信息转换成密文,一般用于客户端向服务器发送密码等敏感信息,发送之前对此信息加密,然后在服务器再进行解密。
0x1 散列
Node.js
生态有很多依赖,例如 Bcrypt 和 Argon2,本身使用起来很简单,这次使用 Bcrypt
来实现散列过程:
yarn add bcrypt
yarn add @types/bcrypt -D
然后对散列的业务进行封装:
import { Injectable } from '@nestjs/common'
import * as bcrypt from 'bcrypt'
@Injectable()
export class BcryptService {
private static readonly SALT_ROUNDS: number = 10
/**
* 对比检查密码
* @param rawStr
* @param hashedStr
*/
async compare(rawStr: string, hashedStr: string) {
return bcrypt.compare(rawStr, hashedStr)
}
/**
* 生成 hash
* @param rawStr
* @param salt
*/
async hash(rawStr: string, salt?: string) {
return bcrypt.hash(rawStr, salt || BcryptService.SALT_ROUNDS)
}
/**
* 生成盐
*/
async genSalt() {
return bcrypt.genSalt(BcryptService.SALT_ROUNDS)
}
}
0x2 加密
Node.js
系统内自带 加密模块,可用于加密和解密等相关操作,下面进行使用 AES-256-CTR
加密方式对数据进行加密:
import { createCipheriv, randomBytes } from 'crypto'
import { promisify } from 'util'
const iv = randomBytes(16)
const password = 'Password used to generate key'
// 密钥长度取决于算法
// 在 aes256 情况下是 32 个字节长度
const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer
const cipher = createCipheriv('aes-256-ctr', key, iv)
const textToEncrypt = 'Nest'
const encryptedText = Buffer.concat([
cipher.update(textToEncrypt),
cipher.final()
])
如果需要解密也很简单:
import { createDecipheriv } from 'crypto'
const decipher = createDecipheriv('aes-256-ctr', key, iv)
const decryptedText = Buffer.concat([
decipher.update(encryptedText),
decipher.final()
])