node.js - AES256 CBC 的 Node.js 实现存在问题

标签 node.js cryptography cbc-mode

首先我要说的是我对密码学非常陌生。我正在尝试实现 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 将被记住用于下一个 updatefinal称呼。

现在,当您调用console.log((encrypt(data)));时,您没有将密文传递给解密函数,该函数不知道下一个 console.log(decrypt(encrypt(data))); 的中间密文 block .

这是一个例子:

enter image description here

The last 16 entries are correct.

这是因为 CBC 不是错误传播模式。您同时加密了两个 block 。由于 decrypt 的第二个密文 block 完好无损,它将正确解密。

关于node.js - AES256 CBC 的 Node.js 实现存在问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35031521/

相关文章:

javascript - crypto.sign Text() 不要求用户提供证书

Perl 地穴 :CBC encrypts/decrypts only first list

php - 从 PHP RIJNDAEL_128 CBC 解密 Node.js 中的字符串

node.js - NodeJS 请求库如何获取完整的 URL,包括 URI 和查询字符串参数

http - 在获取大量图像下载时在 Node.js http.get 中包含超时

node.js - socket.io xhr-轮询断开事件

android - java.io.IOException : Unexpected crypto version 0 异常

javascript - 卡夫卡 : Reading off __consumer_offsets with node-rdkafka

python - 选择字符串作为随机种子对输出的影响

java - 在Java中创建8字节IV