加密和解密后文件末尾的垃圾

时间:2016-10-11 21:28:12

标签: c++ encryption crypto++

我正在尝试加密和解密文件(文本或任何文件),所以我决定使用Crypto ++。以下是我的代码。

crypt.h

#ifndef CRYPT_HPP_
# define CRYPT_HPP_

# include <crypto++/aes.h>
# include <crypto++/osrng.h>
# include <crypto++/blowfish.h>
# include <crypto++/eax.h>
# include <crypto++/files.h>
# include <iostream>

using namespace CryptoPP;
using namespace std;

class Crypt
{
  public:
    Crypt() {};
    ~Crypt() {};

    int init();
    int encrypt(const string &file);
    int decrypt(const string &file, int const);

    AutoSeededRandomPool  _randomGenerator;
    SecByteBlock          _aesKey, _aesIV;
};

#endif /* !CRYPT_HPP_ */

crypt.cpp

int Crypt::init()
{
    try
    {
        _aesKey.New(Blowfish::DEFAULT_KEYLENGTH);
        _aesIV.New(Blowfish::BLOCKSIZE);

        _randomGenerator.GenerateBlock(_aesKey, _aesKey.size());
        _randomGenerator.GenerateBlock(_aesIV, _aesIV.size());
    }
    catch (CryptoPP::Exception &e)
    {
        cerr << e.what() << endl;
        return (-1);
    }
    return (0);
}

加密和解密使用:

执行
int Crypt::encrypt(const string &fileToEncrypt)
{
    EAX< Blowfish >::Encryption e1;
    e1.SetKeyWithIV(_aesKey, _aesKey.size(), _aesIV);

    string encryptedFile = "crypt.txt";
    FileSource fs1(fileToEncrypt.c_str(), true,
                   new AuthenticatedEncryptionFilter(e1,
                        new FileSink(encryptedFile.c_str())));
    return (0);
}

int Crypt::decrypt(const string &fileToDecrypt)
{
    EAX< Blowfish >::Decryption e1;
    e1.SetKeyWithIV(_aesKey, _aesKey.size(), _aesIV);

    string finalFile = "decrypt.txt";
    FileSource fs1(fileToDecrypt.c_str(), true,
                   new AuthenticatedEncryptionFilter(e1,
                        new FileSink(finalFile.c_str())));
    return (0);
}

问题在于,当我解密并获取最终文件时,我实际上得到了正确的输出PLUS一些奇怪的二进制内容。像这样(加密然后解密一个Makefile,我跳到最后,因为这是最有趣的部分):

 fclean: clean
     $(RM) $(NAME)
     $(RM) $(TEST)
     $(RM) -R $(OBJDIR)

 re: fclean all
 �ٌ[�MT̨z���,�o% 

有人已经面临这个问题吗?或者有人可以帮助我吗?

谢谢!

1 个答案:

答案 0 :(得分:-1)

所以...我找到了一个解决方案,但这是真正有价值的解决方案。我只找到了一个小技巧来完成这项工作。

要求:在加密文件之前,您需要文件的大小。

这是我修改过的解密方法:

 int                     Crypt::decrypt(const string &fileToDecryptName, const string &finalFileName,
                                      int const previousSize) {
  EAX<AES>::Decryption  decryption;
  ofstream              finalFile;
  ifstream              tmpFile;
  std::vector<char>     buffer(previousSize);

  try {
    decryption.SetKeyWithIV(_aesKey, _aesKey.size(), _aesIV);
    FileSource fs1(fileToDecryptName.c_str(), true,
              new AuthenticatedEncryptionFilter(decryption, new FileSink("tmp")));
  } catch (Exception &e) {
    std::cerr << e.what() << std::endl;
    return (-1);
  }

  finalFile.open(finalFileName.c_str());
  tmpFile.open("tmp");
  tmpFile.seekg(0, std::ios::beg);
  if (tmpFile.is_open() && tmpFile.read(buffer.data(), previousSize)) {
    if (finalFile.is_open()) {
      finalFile.write(buffer.data(), previousSize);
    } else {
      finalFile.close();
      tmpFile.close();
      throw CommonError("Error : the destination file cannot receive the decrypted content.");
    }
  } else {
    finalFile.close();
    tmpFile.close();
    throw CommonError("Error : decryption cannot be done due to an unexisting or empty file.");
  }
  finalFile.close();
  tmpFile.close();
  return (0);
}

TL; DR :我将解密的内容放入临时文件然后我打开它,读取其内容并复制数据( finalFile .write(buffer.data(),previousSize) 实际上将数据复制到最终文件,直到达到previousSize字符)。这就是你如何摆脱文件末尾的垃圾。