加密和哈希 Encryption and Hashing

加密是对信息进行编码的过程。此过程将信息的原始表示形式(称为明文)转换为另一种形式(称为密文)。

理想情况下,只有授权方才能将密文解密回明文并访问原始信息。加密本身并不能防止干扰,但可以阻止潜在拦截者获取可理解的内容。加密是一种双向函数;加密的内容可以使用正确的密钥解密。

哈希 是将给定密钥转换为另一个值的过程。哈希函数用于根据数学算法生成新值。哈希完成后,应该不可能从输出转到输入。

加密

Node.js 提供了一个内置的 加密模块,您可以使用它来加密和解密字符串、数字、缓冲区、流等。 Nest 本身不在此模块之上提供任何附加包,以避免引入不必要的抽象。

作为示例,我们使用 AES(高级加密系统)'aes-256-ctr' 算法 CTR 加密模式。

ts
import { createCipheriv, randomBytes, scrypt } from 'node:crypto'
import { promisify } from 'node: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(),
])

现在解密encryptedText值:

ts
import { createDecipheriv } from 'node:crypto'

const decipher = createDecipheriv('aes-256-ctr', key, iv)
const decryptedText = Buffer.concat([
  decipher.update(encryptedText),
  decipher.final(),
])

哈希

对于哈希,我们建议使用 bcryptargon2 包。 Nest 本身不在这些模块之上提供任何额外的包装器,以避免引入不必要的抽象(缩短学习曲线)。

作为示例,让我们使用 bcrypt 来哈希随机密码。

首先安装所需的包:

shell
$ npm i bcrypt
$ npm i -D @types/bcrypt

安装完成后,您可以使用 hash 函数,如下所示:

ts
import * as bcrypt from 'bcrypt'

const saltOrRounds = 10
const password = 'random_password'
const hash = await bcrypt.hash(password, saltOrRounds)

要生成盐,请使用 genSalt 函数:

ts
const salt = await bcrypt.genSalt()

要比较/检查密码,请使用 compare 函数:

ts
const isMatch = await bcrypt.compare(password, hash)

您可以在 此处 阅读有关可用函数的更多信息。