【问题标题】:Can't delete file after encrypting content with FileSource使用 FileSource 加密内容后无法删除文件
【发布时间】:2018-01-13 18:36:36
【问题描述】:

我正在尝试使用 AES EAX 模式和 CryptoPP 库加密文件。 下面是 main() 内容:

SecByteBlock key(AES::MAX_KEYLENGTH);
rnd.GenerateBlock(key, key.size());
ArraySource as(key.begin(), key.size(), true, new FileSink("key.bin"));

SecByteBlock iv(AES::BLOCKSIZE);
rnd.GenerateBlock(iv, AES::BLOCKSIZE);

EAX<AES>::Encryption encryptor;
encryptor.SetKeyWithIV(key, key.size(), iv, iv.size());

FileSink file("image.jpg.enc");

ArraySource write_iv(iv, iv.size(), true, new Redirector(file));

FileSource write_ciphertext("image.jpg", true, new AuthenticatedEncryptionFilter(encryptor, new Redirector(file)));

const int delete_file = std::remove("image.jpg");
std::cout << delete_file << std::endl;
std::cout << "Error code is:" << GetLastError();

return 0;

加密部分成功结束,但是,删除原始文件(image.jpg)失败。我得到的输出是:

Error code is:32

这是一个ERROR_SHARING_VIOLATION,意思是“该进程无法访问该文件,因为它正被另一个进程使用。” 我的问题是:如何在 Filesource 行之后关闭文件,以便能够在之后删除文件?使用经典的ifstream,它将是file.close(),但是我如何使用 Crypto++ 来做到这一点?

【问题讨论】:

  • 可能在 FileSource 的析构函数执行之后。
  • ArraySource as(key.begin(), key.size(), true, new FileSink("key.bin")); - 看起来对称密钥正以纯文本形式写入文件系统。
  • 是的,对称密钥是用纯文本编写的,但仅用于测试目的,而我试图删除原始文件

标签: c++ windows encryption crypto++


【解决方案1】:

我不熟悉 crypto++,但如果他们遵循 RAII 模式,那么触发 ~FileSource 析构函数应该足以关闭文件句柄。

在 C++ 中,您将使用匿名范围来定义自动变量的生命周期。匿名作用域使用大括号定义,不带任何关键字:

using namespace std;
...
encryptor.SetKeyWithIV(key, key.size(), iv, iv.size());

// begin an anonymous scope:
{

    FileSink    file             ( "image.jpg.enc" );
    ArraySource write_iv         ( iv, iv.size(), true, new Redirector( file ) );
    FileSource  write_ciphertext ( "image.jpg", true, new AuthenticatedEncryptionFilter( encryptor, new Redirector( file ) ) );        
}
// end the scope, causing all objects declared within to have their destructors called

const int delete_file = remove("image.jpg");
cout << delete_file << endl;
cout << "Error code is:" << GetLastError();
...

顺便说一句,我注意到您使用 new 而不使用 delete。我相信您可以使这些参数对象也自动进行,如下所示:

using namespace std;
...
encryptor.SetKeyWithIV(key, key.size(), iv, iv.size());

// begin an anonymous scope:
{       
    FileSink                      file            ( "image.jpg.enc" );
    Redirector                    write_redir     ( file );
    ArraySource                   write_iv        ( iv, iv.size(), true, &write_redir );
    AuthenticatedEncryptionFilter filter          ( encryptor, &write_redir )
    FileSource                    write_ciphertext( "image.jpg", true, &filter );
}
// end the scope, causing all objects declared within to have their destructors called

const int delete_file = remove("image.jpg");
cout << delete_file << endl;
cout << "Error code is:" << GetLastError();
...

【讨论】:

  • 它就像一个魅力!非常感谢,我已经在这个问题上搜索了几个小时。
  • “我注意到你使用 new 而不删除。我相信你可以使这些参数对象也自动......” - 不太正确。前面的或外部的对象拥有指针。拥有对象在不再需要时删除附加的转换(例如被破坏时)。它是一种不寻常的模式,它是一种后天习得的品味。另请参阅 Crypto++ wiki 上的 Pipelining | OwnershipCrypto++ explicit destruction during encryption/decryption?
猜你喜欢
  • 2019-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-03
  • 1970-01-01
  • 2023-04-05
  • 2012-06-19
相关资源
最近更新 更多