1

私は暗号化に非常に慣れていないと言って始めましょう。Node.js でCipher Block Chaining Modeを実装しようとしています。

私の問題は、復号化なしの暗号化の後、1 つの復号化関数呼び出しで機能しなくなることです。これが私のコードです:

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関数が常に機能していることを確認するにはどうすればよいですか?

4

1 に答える 1

1

TL;DR: これは予期された動作です。

暗号ブロック連鎖 (CBC)モードを使用しています。暗号化と復号化の 1 つのブロック (16 バイト) は、のブロックに依存します。ブロック暗号は疑似ランダム順列です。つまり、16 バイトのデータを与える限り、常に暗号化または復号化します。

コードconsole.log(decrypt(encrypt(data)));を使用して、2 つのブロックを暗号化し、それらを復号化します。update処理された最後の暗号文ブロックは、次のまたはfinal呼び出しのために記憶されます。

を呼び出すとconsole.log((encrypt(data)));、次の中間暗号文ブロックがわからない復号化関数に暗号文が渡されませんconsole.log(decrypt(encrypt(data)));

以下に図を示します。

ここに画像の説明を入力

最後の 16 エントリは正しいです。

これは、CBC がエラー伝搬モードではないためです。同時に 2 つのブロックを暗号化しています。の 2 番目の暗号文ブロックdecryptはそのままであるため、正しく復号化されます。

于 2016-01-27T09:32:01.253 に答える