2017-01-23 18 views
1

私はCrypto++クラスを使用する方法を学ぼうとしています。私の目標は、RSA暗号化用の公開鍵と秘密鍵を生成し、次に平文の基本的な暗号化と復号化を行うことです。Crypto ++ RSAESクラスのメモリリーク

だから私は、彼らの例from here取っている - 少し読みやすくするために変更され、 "フィルタを使用してRSA暗号化スキーム(OAEPおよびSHA)" を:

この部分をOKに動作します:

CryptoPP::AutoSeededRandomPool rng; 

    //Generate Parameters 
    CryptoPP::InvertibleRSAFunction params; 
    params.GenerateRandomWithKeySize(rng, 3072); 

    //Create Keys 
    CryptoPP::RSA::PrivateKey privateKey(params); 
    CryptoPP::RSA::PublicKey publicKey(params); 

    std::string plain="Hello world!", cipher, recovered; 

    //Encryption 
    CryptoPP::RSAES_OAEP_SHA_Encryptor e(publicKey); 

しかし、私はこのブロックを呼び出すとき:

CryptoPP::StringSink* pSS = new CryptoPP::StringSink(cipher); 
    CryptoPP::PK_EncryptorFilter* pEF = new CryptoPP::PK_EncryptorFilter(rng, e, pSS); 

    CryptoPP::StringSource ss1(plain, true, pEF); 

それはメモリリークの原因となります。

Detected memory leaks! 
Dumping objects -> 
{24781} normal block at 0x029BCFF8, 28 bytes long. 
Data: <class CryptoPP::> 63 6C 61 73 73 20 43 72 79 70 74 6F 50 50 3A 3A 
{24780} normal block at 0x029BCFB0, 8 bytes long. 
Data: <  > F8 CF 9B 02 00 00 00 00 
Object dump complete. 

OKをので、私は最も明白なことをしたし、これらを追加しました:私はVisual Studio出力ウィンドウに次のように取得

delete pEF; 
    delete pSS; 

が、それは未処理の例外を発生させたので、私は1つのことを想定しましたCrypto ++クラスのデストラクタはそれらのオブジェクトのいくつかを削除しました。

質問があります - この漏れはどこから来ていますか?

Visual StudioデバッガでStringSinkPK_EncryptorFilterStringSourceに進んでみましたが、そのコードは非常に複雑になっています。

これらのメモリリークを修正するにはどうすればよいですか?

+1

確かにあなたは[mcve] –

+0

@ jwwにあなたのリークをトリミングすることができます:私は自分自身の2番目の質問に答えることができました。私のOPの編集を見てください。 – c00000fd

+0

@jww:ねえ!私はちょうどその第2の問題の解決策を掲示し、それを削除した。 WTF? – c00000fd

答えて

0

メモリリークが発生します。私は、Visual Studio 出力ウィンドウに、次を得る:

Detected memory leaks! 
Dumping objects -> 
{24781} normal block at 0x029BCFF8, 28 bytes long. 
Data: <class CryptoPP::> 63 6C 61 73 73 20 43 72 79 70 74 6F 50 50 3A 3A 
{24780} normal block at 0x029BCFB0, 8 bytes long. 
Data: <  > F8 CF 9B 02 00 00 00 00 
Object dump complete. 

あなたが使用したコードは、少しビット珍しい見えますが、私はその整形と信じています。

あなたが見ているものは、Microsoftの何十年もの古いバグtypeinfo.name() memory leaksです。 VC 5.0以降またはVC 6.0日以降に使用されています。上記のコードを次の

CryptoPP::StringSource ss(plain, true, 
    new CryptoPP::PK_EncryptorFilter(rng, e, 
     new CryptoPP::StringSink(cipher))); 

すべてが赤ニシンです:ここでは


CryptoPP::StringSink* pSS = new CryptoPP::StringSink(cipher); 
CryptoPP::PK_EncryptorFilter* pEF = new CryptoPP::PK_EncryptorFilter(rng, e, pSS); 

CryptoPP::StringSource ss1(plain, true, pEF); 

は、パイプラインは、多くの場合、次のようになります。 Microsoftはバグを修正しないため、あなたはウサギの穴を塞いだ。


OK、私は最も明白なことをしたし、これらを追加しました:

delete pEF; 
delete pSS; 

が、それはええ、それは右ではなかった

未処理の例外が発生しました。 Aのコンストラクタは、Aは所有している(例えば、int型とcharとしてプリミティブ型を除く)オブジェクトBへのポインタを取る場合

*重要な使用上の注意

  1. *:Readme.txtからAの破壊時にB を削除します。 Aのコンストラクターが オブジェクトBへの参照を取得する場合、呼び出し元はBの所有権を保持し、Aが不要になるまで を破棄してはいけません。

  2. Crypto ++はクラスレベルでスレッドセーフです。つまり、マルチスレッドアプリケーションでCrypto ++を安全に使用できますが、複数のスレッドが共通のCrypto ++オブジェクトにアクセスする場合は、 の同期を提供する必要があります。

pEFpSSはポインターたし、彼らは他の誰かが所有していました。彼らは2回削除され、例外が発生しました。


暗号++ RSAESクラスのメモリリーク...

あなたがcryptest.exeプログラムを実行した場合は、60のまたは80漏れが報告されたが表示されます。私は約10年または15年間このバグの解決策を見つけようとしました。最近はStack OverflowでHow to remediate Microsoft typeinfo.name() memory leaks?でした。

EDITまた、ユーザーリストとCommit 301437e693fe8bffWindows Debug build memory leaks clearedを参照してください。ライブラリは動的初期化から静的初期化に移行し、Microsoftプラットフォームの問題を回避しました。静的イニシャライザリストは、Windowsではinti_segでアクセスされます。 GCCの属性はconstructorinit_priorityです。

静的初期化を使用する場合は、その「ベストエフォート」を使用します。それ以外の場合は、動的初期化に戻ります。ここで、「静的初期化」とは、コンストラクタ関数を実行し、グローバルオブジェクトctors(バニラC++静的オブジェクトではない)を呼び出すCRT静的初期化リストにライブラリを取り込むことを意味します。

+0

ありがとうございます。そして、はい、他の情報源では、人々がマイクロソフトのコンパイラを責めていることがわかりました。しかし、もし私が 'CryptoPP' v.5.6.5からv.5.6.2にダウングレードすれば、メモリリークは消え去るでしょうか? – c00000fd

+0

@ c00000fd - わかりません。ロットは5.6.2から5.6.5の間で変更されました。あなたのフルプログラムも見ていません。しかし、あなたが示す症状はマイクロソフトのバグです。最初に、割り当てられた 'N' ***は内部(ランタイム)識別子'クラスCryptoPP :: 'をダンプします。次に、データダンプによって*** N + 1 ***に直ちに続きます。注:VS2015でクラスと名前を追跡する内部スキームが変更されました。それらはもはやメモリダンプの間は連続していません。 – jww

+0

あなたの理論を確認する簡単な道を行くのはいかがですか? VS2008でコンパイルできるtypeinfo.name()リークを示す簡単な例を投稿できますか?コードのたった2〜3行の何か。 – c00000fd

関連する問題