javascript - 使用Node的 'crypto'模块时是否需要使用 key 派生?

标签 javascript node.js encryption

我需要在 NodeJS 应用程序中使用用户的密码实现对称加密。当使用crypto.createCipheriv()时,我是否需要对密码短语执行某种 key 派生以获得 key 参数的值,或者仅按原样传递用户的密码短语就足够了,并且这由实现处理?

最佳答案

密码不应直接用作 key ,但可用于通过 KDF 生成 key 。这是因为 key 预计具有一定的大小,并且密码很弱 - 它们仅使用有限的字节集并且通常包含单词。这使得它们容易受到暴力攻击和字典攻击。 KDF 不仅产生长而统一的 key ,而且还引入了工作因素,使得暴力攻击变得不切实际。

createCipheriv() 不会修改 key 内容或大小。文档中没有提到这一点,但是根据源代码(从 createCipheriv: source ,到 Cipheriv: source ,到 createCipherWithIV: source ,到 prepareSecretKey: source ),我们看到 key 按原样使用。因此, key 应该具有合适的大小并且应该具有足够的复杂性。

Crypto 提供了两种基于密码的 KDF:scrypt 和 PBKDF2。最好使用scrypt,因为它在CPU和内存资源方面非常昂贵,并且可以调整为并行处理,而PBKDF2只消耗CPU资源。两个 KDF 都需要盐,盐应该很长且随机。

使用 scrypt 创建 key :

const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.scryptSync('password', salt, keySize);

使用 pbkdf2 创建 key :

const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.pbkdf2Sync('password', salt, 10000, keySize, 'sha256');

其中“sha256”是底层哈希,10000 是建议的最小迭代次数,它决定了工作因子。在 scrypt 中,一般工作因子是一个可选参数,默认值为 16384 (2^14),可以在 options['cost'] 中设置,我们还可以在其中设置 block 大小和并行度。这些值可以增加很多,具体取决于操作系统;每个操作大约需要 100 毫秒。

最后,Argon2 被认为是一个非常好的 KDF,与 scrypt 一样,它可以针对 CPU 和内存消耗以及并行处理进行调整。尽管 Argon2 在 crypto 中不可用,但它是由其他 Node.js 包提供的。

关于javascript - 使用Node的 'crypto'模块时是否需要使用 key 派生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54994413/

相关文章:

node.js - 无法在中间件中获取 JWT token

node.js - PM2 监控与 PM2 日志

ruby - Ruby 中的 AES-256-GCM 加密和 Golang 解密

c# - 8 字节纯文本的 DES 加密结果为 16 字节数组

javascript - 将光标移动到设计模式 iframe 的开头

javascript - Bootstrap Navbar 下拉菜单不工作 Rails

javascript - 嵌入 Google map 或日历时出现错误 "Failed to load resource: The server responded with a status of 404()"

javascript - Discord.js | guild.iconURL 在嵌入中不起作用

javascript - 删除按钮不起作用

java - 无法在 Android 上使用 AES 密码