Nest.js 散列和加密

淮城一只猫 编程技术 阅读量 0 评论量 0

0x0 前言

散列是给键值经过数学算法转换另外一个键值,在转换过程中是利用哈希函数生成,输出的内容无法还原,这边主要用于密码存储在数据需要进行散列处理。

加密是对信息编码,将原始信息转换成密文,一般用于客户端向服务器发送密码等敏感信息,发送之前对此信息加密,然后在服务器再进行解密。

0x1 散列

Node.js 生态有很多依赖,例如 BcryptArgon2,本身使用起来很简单,这次使用 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()
])

0x3 参考

Encryption and Hashing

Node.js crypto

node.bcrypt.js

喵~