【发布时间】:2020-08-09 14:50:03
【问题描述】:
我想使用 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,他给了我一些重要的提示,我现在更新了我的代码。我希望现在一切都好。
【问题讨论】:
-
stretchString(password, 'salt', 24 + 48);盐应该是不可预测的并且至少 16 个字节。它可以附加/附加到密文中,不需要是秘密。keyPlusHashingSalt.slice(0, 24)AES-256 需要一个 32 字节的密钥; 24 字节为您提供 AES-192。最好坚持使用 AES-128 或 AES-256。 AES-192 没有任何问题,但一些实现不支持它,因此它是最不便携的。hashingSalt: keyPlusHashingSalt.slice(24)这应该是静脉注射吗? IV 必须是 16 个字节。
标签: node.js encryption aes cryptojs