Crypto++RSAES类内存泄漏

Memory leak in Crypto++ RSAES class

本文关键字:泄漏 内存 Crypto++RSAES      更新时间:2023-10-16

我正在尝试学习如何使用Crypto++类。我的目标是为RSA加密生成公钥和私钥,然后对明文进行基本的加密和解密。

因此,我从这里举了他们的例子——">RSA加密方案(OAEP和SHA)使用过滤器",为了可读性稍作修改:

此部件工作正常:

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);

它会导致内存泄漏。我在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.

好吧,所以我做了最明显的事情,并添加了这些:

delete pEF;
delete pSS;

但它导致了一个未处理的异常,所以我假设Crypto++类中的一个析构函数负责删除其中的一些对象。

所以问题是,泄漏是从哪里来的?

我试着用Visual Studio调试器进入StringSinkPK_EncryptorFilterStringSource,看看发生了什么,但要马上弄清楚,代码相当复杂。

知道如何修复内存泄漏吗?

它会导致内存泄漏。我在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.

您使用的代码看起来有点不寻常,但我相信它的格式很好。

我相信你看到的是微软几十年前的错误typeinfo.name()内存泄漏。它出现在VC 5.0或VC 6.0时代。


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

管道通常是这样的:

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

遵循上面代码的一切都是转移注意力。你陷入了一个兔子洞,因为微软不会修复他们的错误。


好吧,所以我做了最明显的事情,添加了这些:

delete pEF;
delete pSS;

但它导致了一个未处理的异常

是的,那不对。从Readme.txt:

*重要使用说明*

  1. 如果a的构造函数将指针指向对象B(除了int和char等基元类型),则a拥有B并将删除B在A的毁灭。如果a的构造函数引用对象B,则调用者保留B的所有权,不应销毁它,直到A不再需要它。

  2. Crypto++在类级别是线程安全的。这意味着您可以在多线程应用程序中安全地使用Crypto++,但必须提供当多个线程访问一个公共Crypto++对象时进行同步。

pEFpSS是指针,它们由其他人所有。它们被删除了两次,这导致了异常。


Crypto++RSAES类内存泄漏。。。

如果运行cryptest.exe程序,则会报告60或80次泄漏。我试图找到解决这个错误的方法已经有10到15年的时间了。最近的一篇文章是"如何修复Microsoft typeinfo.name()内存泄漏?"?堆栈溢出。

EDIT另请参阅用户列表上清除的Windows调试构建内存泄漏和Commit 301437e693fe8ff。为了避免在Microsoft平台上出现问题,库从动态初始化改为静态初始化。静态初始值设定项列表在Windows上使用inti_seg进行访问;以及具有GCC的CCD_ 9和CCD_。

如果可用的话,使用静态初始化是"最大的努力"。否则,事情将回到动态初始化。在这里,"静态初始化"意味着将库放入CRT静态初始化列表,该列表运行构造函数并调用全局对象actor(而不是普通的C++静态对象)。