2016-08-31 1 views
0

Crypto++を使用しているプロジェクトがあります。暗号化 - リリースモードでのBizzareの動作

暗号++は静的libに構築する独自のプロジェクトです。
私は、Crypto ++クラスのいくつかを使用し、静的なlibでビルドされたさまざまなアルゴリズムを処理する別の大きなプロジェクトを持っています。機能の

二つこれらは以下のとおりです。

long long MyClass::EncryptMemory(std::vector<byte> &inOut, char *cPadding, int rounds) 
{ 
    typedef std::numeric_limits<char> CharNumLimit; 
    char sPadding = 0; 
    //Calculates padding and returns value as provided type 
    sPadding = CalcPad<decltype(sPadding)>(reinterpret_cast<MyClassBase*>(m_P)->BLOCKSIZE, static_cast<int>(inOut.size())); 
    //Push random chars as padding, we never care about padding's content so it doesn't matter what the padding is 
    for (auto i = 0; i < sPadding; ++i) 
     inOut.push_back(sRandom(CharNumLimit::min(), CharNumLimit::max())); 
    std::size_t nSize = inOut.size(); 
    EncryptAdvanced(inOut.data(), nSize, rounds); 
    if (cPadding) 
     *cPadding = sPadding; 
    return nSize; 
} 

//Removing the padding is the responsibility of the caller. 
//Nevertheless the string is encrypted with padding 
//and should here be the right string with a little padding 
long long MyClass::DecryptMemory(std::vector<byte> &inOut, int rounds) 
{ 
    DecryptAdvanced(inOut.data(), inOut.size(), rounds); 
    return inOut.size(); 
} 

どこEncryptAdvancedDecryptAdvancedは暗号++オブジェクトに引数を渡します。

//... 
AdvancedProcessBlocks(bytePtr, nullptr, bytePtr, length, 0); 
//... 

これらの機能は、これまでのところ変更は数ヶ月以来、それらに適用されていない、完璧に働いてきました。 それらのロジックは進化しましたが、それらに渡された呼び出しやデータは変更されませんでした。 if (datasize % BLOCKSIZE)を埋めている

復号化/暗号化されたデータがかなり小さいが、動的なサイズを有しているが、残りの部分を有しています。
例:AES Blocksizeは16です。データは31です。埋め込みは1です。データは現在32です。

暗号化して解読する前の文字列は、画像と同じです。意図したとおり、明らかに機能デバッグモードでこのすべてを実行

Encrypt/Decrypt data

。このプログラムを別のコンピュータ(DLL用にVSをインストールしたもの)で実行しても、違いはありません。データは正しく暗号化され、復号化されます。

リリースモードで同じコードを実行しようとすると、全く異なる暗号化文字列が生成され、正しく復号化されません。「ごみデータ」が復号化されます。誤って暗号化されたデータや復号化されたデータは一貫しています。常に同じゴミ箱が解読されます。キー/パスワードとラウンド/イテレーションはいつも同じです。

追加情報:データは同じ静的ライブラリを使用して同じソリューション内の2つの異なるプログラムからデバッグモードで正しく処理されます(ios_base::binary)。このデバッグ/リリースの問題の原因である可能性がどのような

gitの履歴を数回再確認し、コードで数日間デバッグしましたが、この問題の原因を見つけることができません。もしも(ここではむしろ不可能な)以外の情報があれば、MCVEが必要です。コメントを残してください。

+0

あなたはAdvancedProcessBlocks()はインプレース変換を可能にすることを確認していますか?ドキュメントによると、ProcessBlock()はそれを許可していますが、AdvancedProcessBlocks()が明示的に言うわけではありません。 – Jeremy

+0

ProcessBlock()も同様のデバッグ/リリース動作を示しますか?それに対する答えは手がかりをもたらすかもしれません。 – Jeremy

+0

@Jeremyそれは許しています。私はこれまで数ヶ月間問題なく使用し、デバッグしました。問題は最近始まったばかりです。これまでのところ、誰も以前のバージョンでは何の問題もありませんでした。私は後でそれを調べ、考えられる原因が何であるかを調べる(/質問を更新する)。私が正しく覚えていれば、それはその図書館のある特定の呼び出しでしか起こらなかった。 – Blacktempel

答えて

0

は、どうやらこれはCryptoPPのバグです。 Rijndael/AESの最小鍵長は16ではなく8に設定されています.8バイトの無効な鍵長を使用すると、Rcon値のインプレース配列への範囲外アクセスが発生します。この8バイトの鍵長は現在有効と報告されており、CryptoPPで修正する必要があります。

は、より多くの情報のためthis issue on githubを参照してください。 (会話をオンに行く)

+0

Oof、その実装は、暗号ライブラリのための少し不注意に見えます... (私の肘掛け椅子でここから簡単に言うことができます。) よく問題を追跡しました。 – Jeremy