【发布时间】:2016-10-26 03:01:53
【问题描述】:
使用以下节点js:
var crypto = require('crypto');
var encrypt = function (input, password, callback) {
var m = crypto.createHash('md5');
m.update(password);
var key = m.digest('hex');
m = crypto.createHash('md5');
m.update(password + key);
var iv = m.digest('hex');
console.log(iv);
var data = new Buffer(input, 'utf8').toString('binary');
var cipher = crypto.createCipheriv('aes-256-cbc', key, iv.slice(0,16));
var encrypted = cipher.update(data, 'binary') + cipher.final('binary');
var encoded = new Buffer(encrypted, 'binary').toString('base64');
callback(encoded);
};
var decrypt = function (input, password, callback) {
// Convert urlsafe base64 to normal base64
input = input.replace(/\-/g, '+').replace(/_/g, '/');
// Convert from base64 to binary string
var edata = new Buffer(input, 'base64').toString('binary');
// Create key from password
var m = crypto.createHash('md5');
m.update(password);
var key = m.digest('hex');
// Create iv from password and key
m = crypto.createHash('md5');
m.update(password + key);
var iv = m.digest('hex');
// Decipher encrypted data
var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv.slice(0,16));
var decrypted = decipher.update(edata, 'binary') + decipher.final('binary');
var plaintext = new Buffer(decrypted, 'binary').toString('utf8');
callback(plaintext);
};
为了执行,我运行了这个:
encrypt("uWeShxRrCKyK4pcs", "secret", function (encoded) {
console.log(encoded);
decrypt(encoded, "secret", function (output) {
console.log(output);
});
});
加密似乎工作正常,但是当我尝试解密时,我收到以下错误:
错误:错误:06065064:数字信封 例程:EVP_DecryptFinal_ex:错误解密 在错误(本机) 在 Decipheriv.Cipher.final (crypto.js:202:26)
我对密码学很陌生,所以我真的不知道为什么我会收到这个错误。我现在只需要修复它。
【问题讨论】:
-
1.不应该使用 MD5,它不安全,密码的简单散列也不够安全。 2. 使用随机盐在 HMAC 上迭代大约 100 毫秒(盐需要与哈希一起保存)。使用 password_hash、PBKDF2、Bcrypt 等函数或类似函数。关键是让攻击者花费大量时间通过蛮力寻找密码。请参阅 OWASP(开放式 Web 应用程序安全项目)Password Storage Cheat Sheet。
-
谢谢,但我不知道如何更改我的代码来做到这一点。我会尝试看看 bcrypt。
-
调试时间。十六进制转储加密和解密的密钥和 iv,并验证它们是否正确以及长度是否正确。 AES 密钥应该是 32 字节,iv 应该是 16 字节。十六进制转储加密后立即加密和解密前再次加密,验证它们是否相同。
-
如果这是一个有很多用户的严肃应用程序,您需要让领域专家至少审查代码以及如何使用加密。即使对于经验丰富的开发人员来说,加密安全性也很难做到正确。
-
一切似乎都是正确的。我注意到的是,如果我使用比 16 更短的密码,那么一切正常。它似乎与这个问题有关:stackoverflow.com/questions/33586060/… 但是我的代码已经在答案中建议了更改。
标签: node.js encryption openssl cryptography node-crypto