首先我要说的是我对密码学的新手。我试图在Node.js中实现Cipher Block Chaining Mode。
我的问题是,在没有解密的情况下进行加密后,它会停止一次解密函数调用。这是我的代码:
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
函数始终有效?
答案 0 :(得分:1)
TL; DR:这是预期的行为。
您正在使用Cipher-Block Chaining (CBC)模式。加密和解密一个块(16字节)取决于前一个块。分组密码是一种伪随机排列,这意味着只要给它16个字节的数据,它就会一直加密或解密。
使用代码console.log(decrypt(encrypt(data)));
,您可以加密两个块并将它们分配给解密。处理的最后一个密文块将记住下一个update
或final
调用。
现在,当您致电console.log((encrypt(data)));
时,您并未将密文传递给解密函数,而该解密函数并不知道下一个console.log(decrypt(encrypt(data)));
的中间密文块。
以下是一个例子:
最后16个条目是正确的。
那是因为CBC不是错误传播模式。您同时加密了两个块。由于decrypt
的第二个密文块是完整的,它将正确解密。