C ++ AESDecryptとNodejsAESDecryptは異なる出力を生成します

Lothre1

このAESc ++復号化をnodejsに再実装しました。

「バッファ」には暗号化されたコンテンツが含まれています。「decryptKey」には、「バッファ」を復号化するためのキーが含まれています。「expectedOutput」には、期待される出力が含まれています。

ノードによってスローされた不正な復号化例外をバイパスするために、cryptオブジェクトのautoPaddingを無効にする必要がありました。

単純化するために、c ++コードを追加し、3つの異なるアルゴリズム(AES-128-ECB、AES-192-ECB、AES-256-ECB)にテストを追加しました。復号化の結果はいずれもC ++出力と一致しません。

何が足りないのですか?

var crypto = require('crypto');

var buffer = new Buffer([
    0x5e,0x51,0xa3,0x53,0x9d,0xe7,0xe5,0xd3,
    0xee,0x30,0xbb,0xf8,0x0c,0x72,0x9f,0x80
]);


var decryptKey = new Buffer([
    0x36, 0x46, 0xb4, 0xf6, 
    0x8e, 0x6d, 0xdc, 0xf4, 
    0xb0, 0x31, 0x7e, 0x81, 
    0x6b, 0x5d, 0x96, 0x55
])

/*
After looking to my C++ code I noticed that despite of providing a 32 length key the 128 argument ensures that only the first 16 bytes are used
var decryptKey = new Buffer([
    0x36, 0x46, 0xb4, 0xf6, 
    0x8e, 0x6d, 0xdc, 0xf4, 
    0xb0, 0x31, 0x7e, 0x81, 
    0x6b, 0x5d, 0x96, 0x55, // 16
    0x15, 0x9c, 0x78, 0x54, 
    0x8c, 0xca, 0x3e, 0x39, 
    0x2d, 0x49, 0x75, 0x5d, 
    0xa1, 0x1a, 0xc3, 0xe3  // 32
])*/

var expectedOutput = new Buffer([
    0xc8,0x6c,0x8f,0x2b,0xe8,0x21,0xc4,0x2e,
    0xfb,0x4a,0x8e,0x8b,0xc3,0x94,0x19,0xc2
]);

// aes_context aes_ctx;
function decrypt(data, password, algorithm, padding){
  if (padding === void 0) padding = true;
  algorithm = algorithm || 'aes-128-ecb';

  //aes_setkey_dec( &aes_ctx, digest, 128 );
  var crypt = crypto.createDecipher(algorithm,password);
  crypt.setAutoPadding(padding);
  // aes_crypt_ecb( &aes_ctx, AES_DECRYPT, buffer, buffer );
  var res = crypt.update(data, null, 'hex')
  res += crypt.final('hex');

  return new Buffer(res,'hex');
}

// aes_setkey_dec( &aes_ctx, digest, 128 );
var algoList = [
    'aes-128-ecb',
    'aes-192-ecb',
    'aes-256-ecb'
];

for (var i = 0; i<= 1; i++){
    console.log('\n ******* AUTO PADDING: ' + (padding ? 'ON': 'OFF') + ' ********* ');
    var padding = i === 0;
    for (let algo of algoList){
        try {
            var output = decrypt(buffer, decryptKey, algo, padding);
            console.log(algo + ' => ' + output.toString('hex') + ' < ' + (Buffer.compare(expectedOutput, output) === 0 ? 'ok' : 'ko'))
        } catch (err){
            console.log('Failed to perform ' + algo + ' with autopadding ' + (padding ? ' on ': ' off ') + ' due to ' + err.message);
        }
    }
}

/*
 ******* AUTO PADDING: OFF *********
Failed to perform aes-128-ecb with autopadding  on  due to error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
Failed to perform aes-192-ecb with autopadding  on  due to error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
Failed to perform aes-256-ecb with autopadding  on  due to error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

 ******* AUTO PADDING: ON *********
aes-128-ecb => d9817f142f9bca262b67f6a6be570345 < ko
aes-192-ecb => 9181784373bb6060c04c9ba75de26322 < ko
aes-256-ecb => c5945203368de477e5f0dbeedeb2189f < ko
*/

これがC ++コードです

#include "aes.h"
#include "sha2.h"

int main(int argc, char *argv[]) {


    unsigned char data[16] = { 
        0x5e,0x51,0xa3,0x53,0x9d,0xe7,0xe5,0xd3,0xee,0x30,0xbb,0xf8,0x0c,0x72,0x9f,0x80 
    };

    unsigned char key[32] = {
        0x36, 0x46, 0xb4, 0xf6,
        0x8e, 0x6d, 0xdc, 0xf4,
        0xb0, 0x31, 0x7e, 0x81,
        0x6b, 0x5d, 0x96, 0x55, // 16
        0x15, 0x9c, 0x78, 0x54,
        0x8c, 0xca, 0x3e, 0x39,
        0x2d, 0x49, 0x75, 0x5d,
        0xa1, 0x1a, 0xc3, 0xe3  // 32
    };

    aes_context aes_ctx;
    aes_setkey_dec(&aes_ctx, key, 128);
    aes_crypt_ecb(&aes_ctx, AES_DECRYPT, data, data);

    for (int i = 0; i< sizeof(data); ++i)
        std::cout << std::hex << (int)data[i];

    /* Output => c86c8f2be821c42efb4a8e8bc39419c2*/
}

参照:


以下の回答に基づくソリューション

var crypto = require('crypto')
var buffer = new Buffer([
    0x5e,0x51,0xa3,0x53,0x9d,0xe7,0xe5,0xd3,
    0xee,0x30,0xbb,0xf8,0x0c,0x72,0x9f,0x80
]);


var decryptKey = new Buffer([
    0x36, 0x46, 0xb4, 0xf6, 
    0x8e, 0x6d, 0xdc, 0xf4, 
    0xb0, 0x31, 0x7e, 0x81, 
    0x6b, 0x5d, 0x96, 0x55
])

var expectedOutput = new Buffer([
    0xc8,0x6c,0x8f,0x2b,0xe8,0x21,0xc4,0x2e,
    0xfb,0x4a,0x8e,0x8b,0xc3,0x94,0x19,0xc2
]);

// aes_context aes_ctx;
function decrypt(data, password, algorithm, padding){
  if (padding === void 0) padding = true;
  algorithm = algorithm || 'aes-128-ecb';

  //aes_setkey_dec( &aes_ctx, digest, 128 );
  var crypt = crypto.createDecipheriv(algorithm,password, new Buffer([]));//new Buffer(32).fill(0).byteLength
  crypt.setAutoPadding(padding);
  // aes_crypt_ecb( &aes_ctx, AES_DECRYPT, buffer, buffer );
  var res = crypt.update(data, null,'hex')
  + crypt.final('hex');

  return new Buffer(res,'hex');
}

// aes_setkey_dec( &aes_ctx, digest, 128 );
var output = decrypt(buffer, decryptKey, 'aes-128-ecb', false);
console.log(Buffer.compare(expectedOutput, output) === 0 ? 'ok' : 'ko');
rustyx

非推奨の 派生からキーのパスワード引数:crypto.createDecypher()

の実装でcrypto.createDecipher()EVP_BytesToKey、ダイジェストアルゴリズムをMD5に設定し、1回の反復で、ソルトなしでOpenSSL関数使用してキーを派生させます

代わりに必要なのは、生のキーを使用することですそのためには、crypto.createDecipheriv()代わりに次を使用する必要があります

  var crypt = crypto.createDecipheriv(algorithm,password,new Buffer([]));

(ECBモードでは、IVを空にすることができます)

もちろん、キーの長さは要求されたアルゴリズム(128、192、または256ビット)と一致する必要があります。キーは128ビットであるため、aes-128-ecbのみが機能します。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Objective-CはNodeJSとは異なる特殊文字を出力します

分類Dev

Range.Valueは、VBAとC#で異なる結果を生成します

分類Dev

C# プログラムは、ブレークポイントを追加するときに異なるファイルに同じ出力を生成します

分類Dev

同じファイルのC#を使用したZipは、サーバーとWindows10で異なるサイズの出力zipを生成します

分類Dev

Cの配列合計は異なる出力を示します

分類Dev

C#Linqは、デバッグモードで表示される値とは異なる値を出力します

分類Dev

C ++とPythonの同じコードが異なる出力を生成するのはなぜですか?

分類Dev

複数の整数を宣言するC ++は、異なる値を出力します

分類Dev

CとJavaの接尾辞と接頭辞の演算子は異なる結果を生成します

分類Dev

Console.WriteLine(Enum.Value)は、C#とVB.Netで異なる出力を提供します

分類Dev

c#正規表現:パターンとは異なる文字列を出力します

分類Dev

HMC SHA1ハッシュ-C#とは異なるハッシュ出力を生成するJava

分類Dev

C#異なるランダム関数は両方とも同じ値を生成します

分類Dev

Regex.IsMatchはC#で2つの異なる出力を返します

分類Dev

C ++でリストとして出力を生成する方法はありますか?

分類Dev

Cプログラムは奇妙な出力を生成します

分類Dev

Cで「perf_event」を使用してCPUサイクルをカウントすると、「perf」とは異なる値が生成されます

分類Dev

PHPでintをcharに変換すると、C#では出力が異なります。

分類Dev

IndexOfは予想とは異なる動作をしますC#

分類Dev

Cは、最適化レベルに基づいて異なる出力を提供します(新しい例)

分類Dev

C ++ VS17は、Linuxサブシステムの同じコードとは異なる出力を提供します

分類Dev

C ++はPythonとは異なるメッセージを出力します(シリアルポートからの読み取り)

分類Dev

PHPのutf8_decodeとC#のEncoding.UTF8.GetStringは、同じ入力に対して異なる出力を返します

分類Dev

C#とCryptojsのTripleDESCryptoServiceProviderは異なる結果をもたらします

分類Dev

C ++ 20 std :: source_locationは、フリー関数とテンプレート関数の間で異なる列番号を生成します

分類Dev

テキストハッシュのトリックは、PythonとC#で異なる結果を生成します

分類Dev

Visual Studio C ++ 2012および2017は、乱数生成で異なる動作を示しますか?

分類Dev

C#でAutoResetEventとManualResetEventを使用すると、コードの出力が異なるのはなぜですか

分類Dev

私のcプログラムは不要な出力を生成しています

Related 関連記事

  1. 1

    Objective-CはNodeJSとは異なる特殊文字を出力します

  2. 2

    Range.Valueは、VBAとC#で異なる結果を生成します

  3. 3

    C# プログラムは、ブレークポイントを追加するときに異なるファイルに同じ出力を生成します

  4. 4

    同じファイルのC#を使用したZipは、サーバーとWindows10で異なるサイズの出力zipを生成します

  5. 5

    Cの配列合計は異なる出力を示します

  6. 6

    C#Linqは、デバッグモードで表示される値とは異なる値を出力します

  7. 7

    C ++とPythonの同じコードが異なる出力を生成するのはなぜですか?

  8. 8

    複数の整数を宣言するC ++は、異なる値を出力します

  9. 9

    CとJavaの接尾辞と接頭辞の演算子は異なる結果を生成します

  10. 10

    Console.WriteLine(Enum.Value)は、C#とVB.Netで異なる出力を提供します

  11. 11

    c#正規表現:パターンとは異なる文字列を出力します

  12. 12

    HMC SHA1ハッシュ-C#とは異なるハッシュ出力を生成するJava

  13. 13

    C#異なるランダム関数は両方とも同じ値を生成します

  14. 14

    Regex.IsMatchはC#で2つの異なる出力を返します

  15. 15

    C ++でリストとして出力を生成する方法はありますか?

  16. 16

    Cプログラムは奇妙な出力を生成します

  17. 17

    Cで「perf_event」を使用してCPUサイクルをカウントすると、「perf」とは異なる値が生成されます

  18. 18

    PHPでintをcharに変換すると、C#では出力が異なります。

  19. 19

    IndexOfは予想とは異なる動作をしますC#

  20. 20

    Cは、最適化レベルに基づいて異なる出力を提供します(新しい例)

  21. 21

    C ++ VS17は、Linuxサブシステムの同じコードとは異なる出力を提供します

  22. 22

    C ++はPythonとは異なるメッセージを出力します(シリアルポートからの読み取り)

  23. 23

    PHPのutf8_decodeとC#のEncoding.UTF8.GetStringは、同じ入力に対して異なる出力を返します

  24. 24

    C#とCryptojsのTripleDESCryptoServiceProviderは異なる結果をもたらします

  25. 25

    C ++ 20 std :: source_locationは、フリー関数とテンプレート関数の間で異なる列番号を生成します

  26. 26

    テキストハッシュのトリックは、PythonとC#で異なる結果を生成します

  27. 27

    Visual Studio C ++ 2012および2017は、乱数生成で異なる動作を示しますか?

  28. 28

    C#でAutoResetEventとManualResetEventを使用すると、コードの出力が異なるのはなぜですか

  29. 29

    私のcプログラムは不要な出力を生成しています

ホットタグ

アーカイブ