Node.js加密:加密密钥太短

时间:2020-08-09 14:50:03

标签: node.js encryption aes cryptojs

我想用AES-256加密用户数据,以将其安全地存储在我的数据库中。但是,我有一个问题,密钥必须是32个字符长。但是我的用户密码通常要短得多。有什么方法可以“延长”密码的长度?

我还想到了人造密码通常很弱的事实。因此,我需要某种将密码“链接”到加密密钥的功能?

这是我的代码,用于加密和解密:

const crypto = require('crypto');
const algorithm = 'aes-256-cbc';
const key; //Here I would get the password of the user

function encrypt(text) {
   const iv = crypto.randomBytes(16);
   let cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key), iv);
   let encrypted = cipher.update(text);
   encrypted = Buffer.concat([encrypted, cipher.final()]);
   return { iv: iv.toString('hex'), encryptedData: encrypted.toString('hex') };
}

function decrypt(text) {
   let iv = Buffer.from(text.iv, 'hex');
   let encryptedText = Buffer.from(text.encryptedData, 'hex');
   let decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(key), iv);
   let decrypted = decipher.update(encryptedText);
   decrypted = Buffer.concat([decrypted, decipher.final()]);
   return decrypted.toString();
}

非常感谢您提前回答。

更新1.0:

经过研究,我发现以下代码:(Source

const crypto = require('crypto');

// Uses the PBKDF2 algorithm to stretch the string 's' to an arbitrary size,
// in a way that is completely deterministic yet impossible to guess without
// knowing the original string
function stretchString(s, outputLength) {
  var salt = crypto.randomBytes(16);
  return crypto.pbkdf2Sync(s, salt, 100000, outputLength, 'sha512');
}

// Stretches the password in order to generate a key (for encrypting)
// and a large salt (for hashing)
function keyFromPassword(password) {
  // We need 32 bytes for the key
  const keyPlusHashingSalt = stretchString(password, 32 + 16);
  return {
    cipherKey: keyPlusHashingSalt.slice(0, 32),
    hashingSalt: keyPlusHashingSalt.slice(16)
  };
}

如果一切正常,这应该可以解决我的问题:使用上述功能,我可以使用任何密码生成给定长度的安全加密密钥。相同的密码始终与功能keyFromPassword(password)生成相同的加密密钥,对吧?

更新2.0:

由于@President James K. Polk给了我一些重要的提示,我现在更新了我的代码。我希望现在一切都好。

2 个答案:

答案 0 :(得分:1)

您不应直接将用户密码用作密钥。相反,您可以将它们用作诸如pkbdf2之类的密钥派生算法的输入。

this paper on PKBDF2所述:

不幸的是,用户选择的密码通常很短且 缺乏足够的熵[11],[21],[18]。由于这些原因,他们不能 直接用作实现安全密码系统的密钥。该问题的可能解决方案是采用密钥推导 函数(KDF),即采用初始来源的函数 密钥材料并从中派生一个或多个伪随机密钥。

用于计算Node.js的pkbdf2的库,例如found here

答案 1 :(得分:0)

始终在文本中添加salt,并将其附加到文本末尾。该盐可以是任意长度的随机生成的字符串,并且可以轻松满足32个字符的长度限制。此外,在加密之前添加盐会增强加密。