NestJS crypto:promisify(scrypt)的目的是什么?

问题描述 投票:0回答:3

我正在查看 nestjs 加密和哈希文档,它显示了以下内容:

import { createCipheriv, randomBytes, scrypt } from 'crypto';
import { promisify } from 'util';

const iv = randomBytes(16);
const password = 'Password used to generate key';

// The key length is dependent on the algorithm.
// In this case for aes256, it is 32 bytes.
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(),
]);

我无法理解这句话:

const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer;

这是我的问题:

  1. 这条线在做什么?
  2. 为什么我必须这样做?在其他教程中,他们只是使用密钥而不是执行此行。“盐”是什么意思?在方法文档中我只找到了
    arg2: BinaryLike
  3. “盐”是什么意思?在方法文档中我只找到了
    arg2: BinaryLike
node.js typescript nestjs cryptojs
3个回答
2
投票
crypto.scrypt(password, salt, keylen[, options], callback)

crypto.scrypt
是一个采用“错误优先”回调函数的函数:
scrypt
异步派生一个键并调用回调方法返回一个值,向回调传递两个参数
err 
data
(此处
data
是一个缓冲区,记录为
derivedKey
)。

util.promisfy
是一个接受 Function 并返回 Function 的实用程序:您向其传递一个使用错误优先回调的 Function,它返回一个返回 Promise 的 Function,而不是传回回调方法。这允许您使用
await
(如示例代码中所示)以及
then
链接和
Promise.all
等工具。

const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer;
//            This ^^^^^^^^^^^^^^^^^ is just a function based on scrypt.

Salt 是每条记录存储的随机加密值的常用术语;对于

scrypt
,特别是盐“应该尽可能唯一”,建议“盐是随机的且至少 16 个字节长”。更多信息请访问 crypto.SEWikipedia


2
投票

1 这条线在做什么?

promisify
是一个实用程序,可以采用节点样式回调函数(该函数的最后一个参数作为接受错误和结果的函数,例如
fs.readFile('fileToRead', (err, res) => { if (err) throw err; console.log(res); })
)并使其成为承诺的方法,可以是
.then 
ned 或
await
ed。它有助于在现代 JS 生态系统中生成更清晰的代码。

所以有了上面的内容,而不是需要

scrypt(password, salt, 32, (err, result) => doSomethingWithTheResutlAndError(err, result))

你可以这样做

const result = await scrypt(password, salt, 32)

2 为什么我必须这样做? / 3
salt
是什么意思?

我不确定你的意思

arg2: BinaryLike
这是来自 Node 站点的文档

正如OP在评论中发现的,

scrypt
方法是必要的,因为它将密钥转换为
createCipheriv
方法正确的32位缓冲区格式。

一般来说,

salt
是一个额外的(通常是随机的)字符串,在创建哈希时添加,这样当你多次哈希一个字符串时,它会得到不同的值。这有助于在数据库泄漏的情况下提供安全性,因为没有两个密码看起来是相似的,即使它们每次都碰巧是
password123

要了解“其他教程”的含义,您必须展示他们具体在做什么。


对于哈希,我个人使用 bcryptargon2,但是 Node 的

scrypt
模块中的
crypto
方法是另一个不错的选择。


0
投票

因为 crypto.scrypt() 是异步的,但不支持 Promise 编码风格。
事实上:

    const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer;

等于:

    function scryptPromisify(password, salt, keylen, options) {
      return new Promise((resolve, reject) => {
        crypto.scrypt(password, salt, keylen, options, (err, derivedKey) => {
          if (err) {
            reject(err);
          } else {
            resolve(derivedKey);
          }
        });
      });
    }
    const key = await scryptPromise(password, 'salt', 32);
© www.soinside.com 2019 - 2024. All rights reserved.