Javascript 使用Node';时是否需要使用键派生;s';加密';模块?

Javascript 使用Node';时是否需要使用键派生;s';加密';模块?,javascript,node.js,encryption,Javascript,Node.js,Encryption,我需要在NodeJS应用程序中使用用户的密码短语实现对称加密。使用时,是否需要对密码短语执行某种密钥派生,以获取密钥参数的值,或者只按原样传递用户的密码短语就足够了,这由实现来解决吗?破解密码的难度更多地取决于所使用的算法,而不是密码的长度。(省略暴力攻击) 密钥扩展不会增加安全性,因为您在开始时仍然拥有相同的短密码。为了您的安全,请立即假定您有人闯入,并且应用程序代码被泄漏。也就是说,所有标准和自定义算法都是公开的 无论如何,您都必须使用密码扩展,因为大多数算法都需要特定长度的密码 一个更早

我需要在NodeJS应用程序中使用用户的密码短语实现对称加密。使用时,是否需要对密码短语执行某种密钥派生,以获取
密钥
参数的值,或者只按原样传递用户的密码短语就足够了,这由实现来解决吗?

破解密码的难度更多地取决于所使用的算法,而不是密码的长度。(省略暴力攻击)

密钥扩展不会增加安全性,因为您在开始时仍然拥有相同的短密码。为了您的安全,请立即假定您有人闯入,并且应用程序代码被泄漏。也就是说,所有标准和自定义算法都是公开的

无论如何,您都必须使用密码扩展,因为大多数算法都需要特定长度的密码


一个更早的答案,有点离题。 TL;DR:最好的方法是将密码处理到二进制缓冲区(字符串)中

对称加密正是基于这样一个事实,即拥有秘密就可以执行反向操作对称平均运算是可逆的

您的编程语言、框架或库并不重要

在打包加密消息的阶段存在一些差异。您可以接收原始消息或格式精美的消息,其中您在base64中添加了IV和内容

您还必须以相同的方式处理密钥。但是它是关于编码
big-endian
little-endian
和字符编码的,例如:
utf-8
latin2

IV
是一种附加保护,旨在为同一传入消息和机密生成不同的加密消息。但正如您在本节最后一段所述:

它们不必是秘密的:IVs通常只是添加到 未加密的密文消息

总之:你不需要影响加密过程本身,你需要检查电子需要什么样的数据

例如,我的解密过程(在节点中,数据来自PHP):

对于PHP加密:


$data=mcrypt_encrypt($this->_cipher,$this->_key,$data,$this->_mode,$iv);
//使用base64编码转换为字符串
返回base64_编码($iv.$data);
//在哪里
排列(
'key'=>urldecode('urlencode中的secret'),
“密码”=>MCRYPT_RIJNDAEL_128,
“模式”=>MCRYPT\u模式\u CBC,
),

如您所见,我必须找到在两个平台上实现的加密算法,并提供一种在两个平台上提供相同密钥的方法。

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

createCipheriv()
不会修改密钥内容或大小。文档中没有提到这一点,但在源代码之后(从
createCipheriv
:,到
Cipheriv
:,到
createCipherWithIV
:,到
prepareSecretKey
:),我们看到密钥按原样使用。因此,密钥应该具有正确的大小,并且应该具有足够的复杂性

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

使用以下内容创建密钥:

使用以下内容创建密钥:

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


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

我不完全了解您想要做什么。您希望使用用户的密码短语创建对称加密,并将其放在服务器端,以便能够将其用作两侧的种子?我不明白你想用这些东西做什么。您愿意使用密钥分离技术还是只想成功且安全地获得对称密钥?
createCipheriv()
不会修改用户指定的密钥,因此是的,如果您有密码,您应该使用KDF。@DanielVega-否,这是一个电子应用程序,加密用于数据传输synchronized@t.m.adam谢谢这可能是最接近我要找的。我的直觉是不是认为不扩展密码短语是个坏主意?(我目前的想法是将密码短语和用户ID(两者都是使用nanoid生成的,nanoid声称可以从CSPRNG生成声音字符分布)推到Argon2中;在用户设备外,只有ID以明文形式存在,派生密钥缓存在其上,密码短语在平台上尽可能不存在。)是的,切勿将密码用作密钥。Argon2是一个非常好的KDF,但据我所知,
crypto
不支持它。我将使用PBKDF2/scrypt发布一个答案
let crypto = {
  key: Buffer.from('secret in hex', 'hex'),
  cipher: 'aes-128-cbc',
  iv_size: 16
}
    let bData = Buffer.from(data.replace(/ /g,'+'), 'base64');
    let iv = bData.slice(0, crypto.iv_size);
    let text = bData.slice(crypto.iv_size);
    var decipher = crypt.createDecipheriv(crypto.cipher, crypto.key, iv);
    decipher.setAutoPadding(false);
    var decrypted = decipher.update(text,'hex','hex');
    decrypted += decipher.final('hex');
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.scryptSync('password', salt, keySize);
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.pbkdf2Sync('password', salt, 10000, keySize, 'sha256');