0

私はこれを行うのが嫌いですが、 CBC_CTS_Mode_ExternalCipher に関するドキュメントがほとんどまたはまったくないため、イライラしています。

AES128 の部分的に既知のキーがあります。キーの未知の部分と既知の部分のすべての可能な組み合わせと順列を生成する関数を作成しました。言い直します... 申し訳ありませんが、関数は私が望む形式、つまり 16 バイトの 16 バイトでキーを作成しますが、復号化の出力はすべてめちゃくちゃです。メッセージと XOR を復号化するだけでした。 CBC は手動ですが、時間がありません。

復号化が出力されると、あらゆる種類の記号、数字、文字、およびクレイジーさが得られます。

string ciphertext = "C7A4123420BF4EFFB815BC0EA8B46D00F440D068CDD9BB28860DC3E9B312710743";
string plaintext;

CryptoPP::AES::Decryption aesDecryption(tmp, CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_CTS_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, iv );

CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new 
    CryptoPP::StringSink( plaintext ) );

stfDecryptor.Put( reinterpret_cast<const unsigned char*>( ciphertext.c_str() ),
    ciphertext.size() );
stfDecryptor.MessageEnd();

より知識のある人が、これが機能しない理由を説明したり、暗号解読用の暗号文を既に持っている場合に CBC モードで暗号文文字列を復号化するより良い方法を説明したりできますか?

ありがとう

編集:「キーは機能しますが、復号化は機能しません」を置き換えて、言い換えてみましょう...申し訳ありませんが、関数は私が望んでいる形式、つまり16バイトの16バイトでキーを作成しますが、復号化の出力はすべてめちゃくちゃ

4

1 に答える 1

1

暗号解読用の暗号文が既にある場合に、CBC モードで暗号文文字列を復号化するより良い方法

CBC モードではなく、CTS モードを使用しています。したがって、最初のステップは正しいモードを使用することです ;)

以下は、Crypto++ wiki CBC Modeからの CBC 暗号化と復号化の例です。

AutoSeededRandomPool prng;

SecByteBlock key(AES::DEFAULT_KEYLENGTH);
prng.GenerateBlock( key, key.size() );

byte iv[ AES::BLOCKSIZE ];
prng.GenerateBlock( iv, sizeof(iv) );

string plain = "CBC Mode Test";
string cipher, encoded, recovered;

/*********************************\
\*********************************/

try
{
    cout << "plain text: " << plain << endl;

    CBC_Mode< AES >::Encryption e;
    e.SetKeyWithIV( key, key.size(), iv );

    // The StreamTransformationFilter adds padding
    //  as required. ECB and CBC Mode must be padded
    //  to the block size of the cipher.
    StringSource ss( plain, true, 
        new StreamTransformationFilter( e,
            new StringSink( cipher )
        ) // StreamTransformationFilter      
    ); // StringSource
}
catch( const CryptoPP::Exception& e )
{
    cerr << e.what() << endl;
    exit(1);
}

/*********************************\
\*********************************/

// Pretty print cipher text
StringSource ss( cipher, true,
    new HexEncoder(
        new StringSink( encoded )
    ) // HexEncoder
); // StringSource
cout << "cipher text: " << encoded << endl;

/*********************************\
\*********************************/

try
{
    CBC_Mode< AES >::Decryption d;
    d.SetKeyWithIV( key, key.size(), iv );

    // The StreamTransformationFilter removes
    //  padding as required.
    StringSource ss( cipher, true, 
        new StreamTransformationFilter( d,
            new StringSink( recovered )
        ) // StreamTransformationFilter
    ); // StringSource

    cout << "recovered text: " << recovered << endl;
}
catch( const CryptoPP::Exception& e )
{
    cerr << e.what() << endl;
    exit(1);
}

典型的な出力は次のとおりです。

$ ./driver.exe 
key: B00DDF9D93E199EFEAE967805E0A5228
iv: CA8A8878F145C9B9B3C31A1F15C34A6D
plain text: CBC Mode Test
cipher text: D6AF39534926C21CFF3E7477A7146FF3
recovered text: CBC Mode Test

文字列の暗号文 = "C7A4123420BF4EFFB815BC0EA8B46D00F440D068CDD9BB28860DC3E9B312710743"

2 番目にやりたいことは、文字列を 16 進数からバイナリに変更することです。これはHexDecoderの下の Crypto++ wiki でカバーされています。

string encoded = "FFEEDDCCBBAA99887766554433221100";
string decoded;

StringSource ss(encoded,
    new HexDecoder(
        new StringSink(decoded)
    ) // HexDecoder
); // StringSource

上記のコードを実行すると、NULLs が埋め込まれた可能性のあるバイナリ文字列が得られます。したがってdecoded.data()、ポインターとdecoded.size()バイナリ文字列の長さには必ず使用してください。


復号化が出力されると、あらゆる種類の記号、数字、文字、およびクレイジーさが得られます。

これは、復号化が失敗したことを意味する可能性があります。実際に伝える唯一の方法は、暗号テキストに HMAC のような認証タグを提供するかどうかです。それ以外の場合は、それらの結果が得られます。

パディングが必要なモード (CBC モードなど) を使用する場合、パディングがたまたま正しい場合でも、スプリアス ヒットが発生します。明確に伝える唯一の方法は、認証タグを提供することです。


キーの未知の部分と既知の部分のすべての可能な組み合わせと順列を生成する関数を作成しました。

エラーが発生した場合に備えて、そのルーチンも表示する必要があります。ビットを並べ替える方法についてコメントすることはできませんが、Crypto++ が使用するバイナリ文字列を生成するように見えるかどうかについてコメントすることはできます。


メッセージと CBC の XOR を手動で復号化するつもりでしたが、時間がありません。

私は本当にこれをどうすればいいのかわかりません... AES を ECB モードで操作してから、自分で XOR を実行しますか? その場合は、ArrayXorSinkを検討してください。

于 2014-02-21T17:29:53.890 に答える