我有两个函数来加密和解密node.js中的字符串,两者都工作正常,直到输入字符串的长度小于15个字符,超过这个它们将无法工作。下面是我在带有加密模块的nodejs中使用的函数。
encrypt: function (input, password) {
try{
input = input.toString();
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');
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');
return encoded;
}catch (ex) {
return input;
}
},
decrypt: function (input, password) {
try{
// Convert urlsafe base64 to normal base64
var 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');
return plaintext;
}catch (ex) {
return input;
}
}
请帮我解决这个问题。
答案 0 :(得分:1)
让我们看看文档:
cipher.update(data[, input_encoding][, output_encoding])
cipher.final([output_encoding])
你正在做
var encrypted = cipher.update(data, 'binary') + cipher.final('binary');
这意味着update()
调用返回一个Buffer,因为你没有指定输出编码,final()
输出二进制字符串。
当缓冲区通过连接强制转换为字符串时,这两个部分具有不同的编码,并且因为您将其作为new Buffer(encrypted, 'binary')
的单个部分读取,它将在解密期间抛出错误:
[错误:错误:0606506D:数字包络例程:EVP_DecryptFinal_ex:错误的最终块长度]
查看抛出的异常总是一个好主意。目前,如果引发异常,您只是忽略异常ex
。
在加密期间提供输出编码:
var encrypted = cipher.update(data, 'binary', 'binary') + cipher.final('binary');
和解密:
var decrypted = decipher.update(edata, 'binary', 'binary') + decipher.final('binary');
密钥和IV应由字节组成。目前,您正在使用MD5生成256位的十六进制编码密钥。相反,您应该使用二进制输出大小为384位的PBKDF2(数千或数百万次迭代和随机盐)。您可以将前256位用于密钥,其余用于IV。然后你将盐与密文一起发送。
答案 1 :(得分:-3)
你有一个小的IV,它限制为15个字符。 IV的长度应与纯文本相同。您可以多次重复您的密钥以生成大型IV。