繁体   English   中英

在加密/解密过程中,Crypto ++显式销毁?

[英]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,但可以找到我的答案。 我想知道是否需要显式销毁创建的对象?

这取决于。 自述文件中的 重要使用说明下 (列出了两个项目):

  1. 如果A的构造函数使用一个指向对象B的指针(原始类型(如int和char除外)),则A拥有B并在A被破坏时删除B。 如果A的构造函数引用了对象B,则调用者保留对B的所有权,并且在A不再需要它之前不应销毁它的所有权。

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

这是您的代码。 它看起来不错,并且不需要更改。 但是我们可以通过它来保证完整性(为了简洁起见,删除了CryptoPP ):

FileSource(inFile, true, new StreamTransformationFilter(encryptor, new FileSink(outFile)));
  1. 您有基于堆栈的FileSource 它是一个自动变量,超出范围时将被删除。 它的样板C ++。
  2. 你有inFile 它是参考,您有责任删除它。 它基于堆栈,当超出调用方范围时将其删除。 它的样板C ++。
  3. 你有StreamTransformationFilter以创建new 它是一个指针,而FileSource拥有它。 FileSource析构函数运行时,它将被删除。 管道是一种习性。
  4. 你有encryptor 它是参考,您有责任删除它。 它基于堆栈,超出范围时将其删除。 它的样板C ++。
  5. 你有FileSink与创建new 它是一个指针, StreamTransformationFilter拥有它。 StreamTransformationFilter析构函数运行时,它将被删除。 管道是一种习性。
  6. 您有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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM