c++ - 加解密后文件末尾出现垃圾

标签 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);
}

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

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

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

有人遇到过这个问题吗?或者有人可以帮我吗?

谢谢!

最佳答案

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

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

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

 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 个字符)到最终文件中。这就是清除文件末尾垃圾的方法。

关于c++ - 加解密后文件末尾出现垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39987047/

相关文章:

c++ - 如何检查二维数组是否在 C++ 中按升序排列?

java - 安卓 SDK : BASE64 Encoder/Decoder not importing

java - 在C中使用私钥加密数据,在Java中使用公钥解密数据

c++ - Crypto++ CRC32 链接器错误

c++ - 使用引用左值的正确方法

c++ - 从 std::vector<glm::vec3> 获取一个 float 类型的数组指针

c++ - C++为类方法实现超时功能模板

java - AES 加密 256 ECB 模式

c++ - 使用 SecretSharing 时未知 : this object doesn't support multiple channels,

android - 警告 : libcryptopp. so: is missing DT_SONAME 将使用 basename 作为替换