[英]Crypto++ explicit destruction during encryption/decryption?
我编写了一些包装函数,以使用crypto ++加密/解密文件。 我尝试查看Wiki,但可以找到我的答案。 我想知道是否需要显式销毁创建的对象?
我在Wiki中发现,传递给函数的某些对象会为您破坏,但是没有我的确切用法示例,因此我只是想确定一下。
CryptoPP::AutoSeededRandomPool prng;
//Key generation
byte key[AES::DEFAULT_KEYLENGTH];
prng.GenerateBlock(key, sizeof(key));
//IV generation
byte iv[AES::BLOCKSIZE];
prng.GenerateBlock(iv, sizeof(iv));
//print key
encoded.clear();
StringSource(key, sizeof(key), true, new HexEncoder(new StringSink(encoded)));
cout << "key: " << encoded << endl;
cout << "Size of key: " << sizeof(key) << endl;
//print iv
encoded.clear();
StringSource(iv, sizeof(iv), true, new HexEncoder(new StringSink(encoded)));
cout << "iv: " << encoded << endl;
cout << "Size of iv: " << sizeof(iv) << endl;
//See function below
encrypt_file(inFile, outFile, key, iv, err);
inFile.close();
outFile.close();
一旦在此函数中,出于某种原因,字节数组将被截断
bool encrypt_file(std::ifstream& inFile,
std::ofstream& outFile,
const byte* key, const byte* iv,
std::string& errMsg)
{
std::string encoded;
//print key
encoded.clear();
StringSource(key, sizeof(key), true, new HexEncoder(new StringSink(encoded)));
cout << "key: " << encoded << endl;
cout << "Size of key: " << sizeof(key) << endl;
//print iv
encoded.clear();
StringSource(iv, sizeof(iv), true, new HexEncoder(new StringSink(encoded)));
cout << "iv: " << encoded << endl;
cout << "Size of iv: " << sizeof(iv) << endl;
try {
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption e;
e.SetKeyWithIV(key, sizeof(key), iv);
CryptoPP::FileSource(inFile, true, new CryptoPP::StreamTransformationFilter(e, new CryptoPP::FileSink(outFile)));
inFile.close();
outFile.close();
}
catch (CryptoPP::Exception& e) {
errMsg = e.GetWhat();
return false;
}
return true;
}
key: 6574D7BDFD0DD3BC59CD3846D4A196A8
Size of key: 16
iv: 1B4ED692F91A32246B41F63F6B8C6EAA
Size of iv: 16
key: 6574D7BDFD0DD3BC
Size of key: 8
iv: 1B4ED692F91A3224
Size of iv: 8
不,你没有。 您创建的对象具有自动存储期限 ,这意味着它们的析构函数将在其作用域末尾自动调用。 此外,随new
传递的参数将归Crypto ++对象所有,并且它们对应的析构函数将为您释放内存。 它们属于接收器或过滤器的类别,事实证明您也通过了所有权。 有关更多详细信息,请参见:
https://www.cryptopp.com/wiki/管道#所有权
基本上就是这样(超级简化的例子):
#include <iostream>
struct Foo{};
class X
{
Foo *p_;
public:
X(Foo* p): p_(p) {}
// we'd also need a copy ctor and copy assignment operator, ignored here
~X()
{
std::cout << "Releasing the memory...\n";
delete p_;
}
};
int main()
{
X x(new Foo()); // sinking, no memory leak
}
我不得不说,这是迄今为止我最不喜欢的软件设计风格。 可以使用模板和mixin来实现类似的功能(了解基于策略的设计 ),而无需在没有明确所有权的情况下浮动指针。
我编写了一些包装函数,以使用crypto ++加密/解密文件。 我尝试查看Wiki,但可以找到我的答案。 我想知道是否需要显式销毁创建的对象?
这取决于。 从自述文件中的 重要使用说明下 (列出了两个项目):
如果A的构造函数使用一个指向对象B的指针(原始类型(如int和char除外)),则A拥有B并在A被破坏时删除B。 如果A的构造函数引用了对象B,则调用者保留对B的所有权,并且在A不再需要它之前不应销毁它的所有权。
Crypto ++在类级别是线程安全的。 这意味着您可以在多线程应用程序中安全地使用Crypto ++,但是当多个线程访问同一个Crypto ++对象时,必须提供同步。
这是您的代码。 它看起来不错,并且不需要更改。 但是我们可以通过它来保证完整性(为了简洁起见,删除了CryptoPP
):
FileSource(inFile, true, new StreamTransformationFilter(encryptor, new FileSink(outFile)));
FileSource
。 它是一个自动变量,超出范围时将被删除。 它的样板C ++。 inFile
。 它是参考,您有责任删除它。 它基于堆栈,当超出调用方范围时将其删除。 它的样板C ++。 StreamTransformationFilter
以创建new
。 它是一个指针,而FileSource
拥有它。 当FileSource
析构函数运行时,它将被删除。 管道是一种习性。 encryptor
。 它是参考,您有责任删除它。 它基于堆栈,超出范围时将其删除。 它的样板C ++。 FileSink
与创建new
。 它是一个指针, StreamTransformationFilter
拥有它。 当StreamTransformationFilter
析构函数运行时,它将被删除。 管道是一种习性。 outFile
。 它是参考,您有责任删除它。 它基于堆栈,当超出调用方范围时将其删除。 它的样板C ++。 信息在Wiki上,但是如果您不知道要查找的内容,则很难找到它。 另请参见流水线| 维基上的所有权 。
相关,这看起来很可疑:
e.SetKeyWithIV(key, sizeof(key), iv);
因为key
是声明为... byte key[], byte iv[] ...
的函数参数,所以我认为它会衰减为大小为4(i686)或8(x86_64) 的指针 。 您应该使用类似以下的内容,它允许您指定数组的大小:
bool encrypt_file(std::ifstream& inFile,
std::ofstream& outFile,
const byte* key, size_t ksize,
const byte* iv, size_t vsize,
std::string& errMsg)
{
...
e.SetKeyWithIV(key, ksize, iv);
...
}
因此,鉴于:
byte key[AES::DEFAULT_KEYLENGTH];
prng.GenerateBlock(key, sizeof(key));
byte iv[AES::BLOCKSIZE];
prng.GenerateBlock(iv, sizeof(iv));
然后这样称呼它:
encrypt_file(inFile, outFile, key, sizeof(key), iv, sizeof(iv), err);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.