首先我要说的是我对密码学非常陌生。我正在尝试实现 Cipher Block Chaining Mode在 Node.js 中。
我的问题是,在没有解密的加密之后,它停止为一个解密函数调用工作。这是我的代码:
var crypto = require('crypto');
var encryptionMethod = 'aes-256-cbc';
var vector = new Buffer([0xF1, 0x4C, 0xB6, 0xBD, 0x82, 0x93, 0x3C, 0x97, 0x6A, 0x4B, 0x4A, 0xD2, 0xAD, 0xD5, 0xA8, 0x6D]);
var key = new Buffer([59, 92, 128, 239, 136, 26, 19, 26, 226, 234, 53, 71, 157, 113, 209, 96, 111, 83, 167, 123, 217, 107, 124, 31, 238, 176, 58, 110, 161, 82, 81, 69]);
var cipher = crypto.createCipheriv(encryptionMethod, key, vector);
cipher.setAutoPadding(false);
var decipher = crypto.createDecipheriv(encryptionMethod, key, vector);
decipher.setAutoPadding(false);
var encrypt = function(array) {
return cipher.update(new Buffer(array));
};
var decrypt = function(buffer) {
return decipher.update(buffer);
};
var data = [];
for (var i = 0; i < 32; i++) {
data.push(i);
}
// no problem here (probably because the vector updates itself?)
console.log(decrypt(encrypt(data))); // <Buffer 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f>
console.log(decrypt(encrypt(data))); // <Buffer 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f>
console.log(decrypt(encrypt(data))); // <Buffer 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f>
// after one encryption without a decryption it stops working.
console.log((encrypt(data)));
// why can't this be decrypted correctly? The last 16 entries are correct.
console.log(decrypt(encrypt(data))); // <Buffer e2 df 50 63 c7 eb 06 4c 28 19 6d 04 41 bd c0 db 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f>
// expected result
console.log(decrypt(encrypt(data))); // <Buffer 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f>
请参阅 console.log
调用上方的注释以获取更多信息。如何确保decrypt
功能始终有效?
最佳答案
TL;DR:这是预期的行为。
您正在使用Cipher-Block Chaining (CBC)模式。其中一个 block (16 字节)的加密和解密取决于前一个 block 。分组密码是一种伪随机排列,这意味着只要您给它 16 字节的数据,它就始终可以加密或解密任何内容。
使用代码console.log(decrypt(encrypt(data)));
您正在加密两个 block 并将它们交给解密。最后处理的密文 block 将被记住用于下一个 update
或final
称呼。
现在,当您调用console.log((encrypt(data)));
时,您没有将密文传递给解密函数,该函数不知道下一个 console.log(decrypt(encrypt(data)));
的中间密文 block .
这是一个例子:
The last 16 entries are correct.
这是因为 CBC 不是错误传播模式。您同时加密了两个 block 。由于 decrypt
的第二个密文 block 完好无损,它将正确解密。
关于node.js - AES256 CBC 的 Node.js 实现存在问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35031521/