简体   繁体   English

从磁盘而不是内存加密和解密文件?

[英]Encrypt and decrypt a file from disk rather than memory?

When I am trying to encrypt and decrypt a 250MB file using AES algorithm, I am getting the following error.当我尝试使用 AES 算法加密和解密 250MB 文件时,出现以下错误。 When I am trying with datasets less than 250, I am able to get the output.当我尝试使用小于 250 的数据集时,我能够获得输出。

在此处输入图片说明

From the COMMENTS:来自评论:

string cipher, encoded, recovered;
FileSource file("C:/Users/sai/desktop/RA/250.avi", true, new StringSink(plain));

This may or may not work depending on several factors.这可能会或可能不会起作用,具体取决于几个因素。 On a desktop or server you should have no problems because it will have a lot of RAM and a swap file.在台式机或服务器上,您应该没有问题,因为它将有大量 RAM 和交换文件。

On a mobile device it will probably die if the file is large.在移动设备上,如果文件很大,它可能会死。 If it dies then the problem is probably because StringSink is an in-memory string but the device ran out of memory.如果它死了,那么问题可能是因为StringSink是内存中的字符串,但设备内存不足。


From the COMMENTS:来自评论:

... Do I need to break the file into chunks and then encrypt and decrypt? ...我是否需要将文件分成块然后加密和解密?

No, you should not need to break the file into chunks.不,您不需要将文件分成块。 The FileSource will do it for you. FileSource将为您完成。 It will break the data into 4096 chunks, if I recall correctly.如果我没记错的话,它会将数据分成 4096 个块。 What you probably need to do is switch from a StringSink to a FileSink .您可能需要做的是从StringSink切换到FileSink

Also see Pumping Data |另见抽水数据 | Encryption on the Crypto++ wiki.加密的加密+维基。 Here's the sample provided:这是提供的示例:

inline bool EndOfFile(const FileSource& file)
{
  std::istream* stream = const_cast<FileSource&>(file).GetStream();
  return stream->eof();
}

int main(int argc, char* argv[])
{
  try
  {
      byte key[AES::DEFAULT_KEYLENGTH]={}, iv[AES::BLOCKSIZE]={};
      CTR_Mode<AES>::Encryption encryptor;
      encryptor.SetKeyWithIV(key, sizeof(key), iv);

      MeterFilter meter;
      StreamTransformationFilter filter(encryptor);

      FileSource source("plain.bin", false);
      FileSink sink("cipher.bin");

      source.Attach(new Redirector(filter));
      filter.Attach(new Redirector(meter));
      meter.Attach(new Redirector(sink));

      const word64 BLOCK_SIZE = 4096;
      word64 processed = 0;

      while(!EndOfFile(source) && !source.SourceExhausted())
      {
        source.Pump(BLOCK_SIZE);
        filter.Flush(false);

        processed += BLOCK_SIZE;

        if (processed % (1024*1024*10) == 0)
          cout << "Processed: " << meter.GetTotalBytes() << endl;
      }

      // Signal there is no more data to process.
      // The dtor's will do this automatically.
      filter.MessageEnd();
  }
  catch(const Exception& ex)
  {
    cerr << ex.what() << endl;
  }

  return 0;
}

From the TITLE:从标题:

[How to] encrypt and decrypt a file from disk rather than memory? [如何]从磁盘而不是内存加密和解密文件?

Try something like the following.尝试类似以下内容。 Your code is missing the encryption or decryption object, so be sure to include one in the real code.您的代码缺少加密或解密对象,因此请确保在真实代码中包含一个。

FileSource file("C:/Users/sai/desktop/RA/250.avi", true, new FileSink("C:/Users/sai/desktop/RA/250.avi.enc"));

Or, you can use the code that shows you how to manually pump data.或者,您可以使用向您展示如何手动抽取数据的代码。


From the COMMENTS:来自评论:

int start_s = clock();

Also see Benchmarks |另见基准 | Sample Program on the Crypto++ wiki. Crypto++ wiki 上的示例程序 Here's the sample provided:这是提供的示例:

const double runTimeInSeconds = 3.0;
const double cpuFreq = 2.7 * 1000 * 1000 * 1000;

int main(int argc, char* argv[])
{
    using namespace CryptoPP;
    AutoSeededRandomPool prng;

    SecByteBlock key(16);
    prng.GenerateBlock(key, key.size());

    CTR<AES>::Encryption cipher;
    cipher.SetKeyWithIV(key, key.size(), key);

    const int BUF_SIZE = RoundUpToMultipleOf(2048U,
        dynamic_cast<StreamTransformation&>(cipher).OptimalBlockSize());

    AlignedSecByteBlock buf(BUF_SIZE);
    prng.GenerateBlock(buf, buf.size());

    double elapsedTimeInSeconds;
    unsigned long i=0, blocks=1;

    ThreadUserTimer timer;
    timer.StartTimer();

    do
    {
        blocks *= 2;
        for (; i<blocks; i++)
            cipher.ProcessString(buf, BUF_SIZE);
        elapsedTimeInSeconds = timer.ElapsedTimeAsDouble();
    }
    while (elapsedTimeInSeconds < runTimeInSeconds);

    const double bytes = static_cast<double>(BUF_SIZE) * blocks;
    const double ghz = cpuFreq / 1000 / 1000 / 1000;
    const double mbs = bytes / elapsedTimeInSeconds / 1024 / 1024;
    const double cpb = elapsedTimeInSeconds * cpuFreq / bytes;

    std::cout << cipher.AlgorithmName() << " benchmarks..." << std::endl;
    std::cout << "  " << ghz << " GHz cpu frequency"  << std::endl;
    std::cout << "  " << cpb << " cycles per byte (cpb)" << std::endl;
    std::cout << "  " << mbs << " MiB per second (MiB)" << std::endl;   

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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