Son*_*oor 9 encryption openssl cryptography node.js node-crypto
使用以下节点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);
};
Run Code Online (Sandbox Code Playgroud)
为了执行,我运行了这个:
encrypt("uWeShxRrCKyK4pcs", "secret", function (encoded) {
console.log(encoded);
decrypt(encoded, "secret", function (output) {
console.log(output);
});
});
Run Code Online (Sandbox Code Playgroud)
加密似乎工作正常,但当我尝试解密时,我收到以下错误:
错误:错误:06065064:数字信封例程:EVP_DecryptFinal_ex:在Decipheriv.Cipher.final处于错误(本机)时解密错误(crypto.js:202:26)
我对密码学很陌生,所以不知道为什么我收到这个错误.我现在只需修好它.
你混合了两种不同的编码.看到
和
现在来看看
var encrypted = cipher.update(data, 'binary') + cipher.final('binary');
Run Code Online (Sandbox Code Playgroud)
但它应该是
var encrypted = cipher.update(data, 'binary', 'binary') + cipher.final('binary');
Run Code Online (Sandbox Code Playgroud)
问题是cipher.update(data, 'binary')
输出一个缓冲区,它自动字符串化为十六进制编码的字符串而不是"二进制"字符串.
无论如何,这段代码有很多错误,你应该重新开始,只需使用一个高度自以为是的现有库.
你必须有一个随机的IV,它被加在密文之前,以达到语义安全.
密码具有低熵,不能用作密钥.单个MD5调用不会改变这一事实.密码的密钥派生应该是缓慢的,因此使用具有高迭代计数/成本因子的已知方案,例如PBKDF2,bcrypt,scrypt或Argon2(增加安全性).不要忘记盐.
在加密然后MAC方案中使用消息认证代码(例如HMAC-SHA256)验证密文.否则,攻击者可能会操纵密文,您甚至无法检测到更改.使用填充oracle攻击丢失数据的第一步.
小智 5
由于这个问题是第一个出现在 Google 上的问题,因此这里有另一个解决方案。
如果链接断开,就我而言,我必须更新解密函数以添加
function decrypt(text) {
let iv = Buffer.from((text.split(':')[1]).split('=')[0], 'hex')//will return iv;
let enKey = Buffer.from(text.split('=')[1], 'hex')//will return key;
let encryptedText = Buffer.from(text.split(':')[0], 'hex');//returns encrypted Data
let decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(enKey), iv);
// Added this line here
decipher.setAutoPadding(false);
let decrypted = decipher.update(encryptedText);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted.toString();
//returns decryptedData
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7954 次 |
最近记录: |