使用Node的“ crypto”模块时是否需要使用密钥派生?

mil*_*ose 0 javascript encryption node.js

我需要在NodeJS应用程序中使用用户密码来实现对称加密。使用时crypto.createCipheriv(),我是否需要对密码短语执行某种密钥派生以获得key参数值,还是仅按原样传递用户的密码短语就足够了,实现可以解决这个问题?

t.m*_*dam 5

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

createCipheriv()不修改密钥的内容或大小。在文档中没有提到这一点,但是遵循源代码(从createCipherivsourceCipherivsource,到createCipherWithIVsourceprepareSecretKeysource),我们看到密钥被原样使用。因此,密钥应该具有正确的大小,并且应该具有足够的复杂性。

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

使用创建密钥scrypt

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

使用创建密钥pbkdf2

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

其中“ sha256”是基础哈希,而10000是建议的最小迭代次数,它确定了工作因子。在scrypt中,常规工作因子是一个可选参数,默认值为16384(2 ^ 14),可以在中设置options['cost'],我们还可以在其中设置块大小和并行化。根据操作系统的不同,这些值可以增加很多。每次操作大约需要100毫秒。

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