Security

加密和哈希

学习如何在NestJS应用中实现加密和哈希功能,包括密码哈希、数据加密和安全最佳实践

加密和哈希

加密是将信息或数据编码的过程,只有授权方才能访问它。这个过程将原始信息(称为明文)转换为另一种形式(称为密文)。理想情况下,只有授权方才能将密文解密回明文并访问原始信息。加密本身并不能防止干扰,但它会拒绝可理解的内容给潜在的拦截者。加密是一个双向函数;您加密的内容可以被解密,前提是您拥有正确的密钥。

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

加密

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

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

import { createCipheriv, randomBytes, scrypt } 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, 'utf8'),
  cipher.final(),
]);

现在解密encryptedText值:

import { createDecipheriv } from 'crypto';

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

哈希

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

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

首先安装所需的包:

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

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

import * as bcrypt from 'bcrypt';

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

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

const salt = await bcrypt.genSalt();

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

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

有关可用函数的更多信息,请阅读这里