【问题标题】:Passing a key to AES decryption in Crypto++在 Crypto++ 中将密钥传递给 AES 解密
【发布时间】:2018-12-27 00:33:50
【问题描述】:

我已经为此问题进行了很多搜索,但没有找到任何解决方案。在我目前的项目中,我必须使用发送者接收者表单来加密图像。所以我必须在发送方部分生成一个密钥来加密文件,并且我必须使用相同的密钥(作为参数传递给 main)来获取原始数据,以继续执行程序。

我将密钥保存在文本文件中:

   void GetKeyAndIv() {
// Initialize the key and IV
prng.GenerateBlock( key, key.size() );
prng.GenerateBlock(iv, iv.size());
};

    /*********************Begin of the Function***********************/
//Function encrypt a file (original file) and store the result in another file (encrypted_file)
void Encrypt(std::string original_file, std::string encrypted_file_hex,string encrypted_file,string binary) {

    ofstream out;
    out.open("Key.txt");
    out.clear();
    out<<"key = "<< key<<endl;
    out<<"iv = "<< iv<<endl;

    string cipher, encoded;

    //Getting the encryptor ready
    CBC_Mode< CryptoPP::AES >::Encryption e;
    e.SetKeyWithIV( key, key.size(), iv );


  try
  {

        ifstream infile(original_file.c_str(), ios::binary);
        ifstream::pos_type size = infile.seekg(0, std::ios_base::end).tellg();
        infile.seekg(0, std::ios_base::beg);

        //read the original file and print it
        string temp;
        temp.resize(size);
        infile.read((char*)temp.data(), temp.size());
        infile.close();


         // Encryption
CryptoPP::StringSource ss( temp, true,
   new CryptoPP::StreamTransformationFilter( e,
      new CryptoPP::StringSink( cipher )//,
      //CryptoPP::BlockPaddingSchemeDef::NO_PADDING
   ) // StreamTransformationFilter
); // StringSource




 std::ofstream outfile1(encrypted_file.c_str(),ios::out | ios::binary);
  outfile1.write(cipher.c_str() , cipher.size());


  }
catch( const CryptoPP::Exception& e )
{

    cout <<"Encryption Error:\n" <<e.what() << endl;
    system("pause");
    exit(1);
}

然后我使用以下代码将其传递给客户端:

int main(int argc, char* argv[])
{
.....
        string s1=argv[7];
        SecByteBlock b1(reinterpret_cast<const byte*>(&s1[0]), s1.size());
        string s2=argv[8];
        SecByteBlock iv1(reinterpret_cast<const byte*>(&s2[0]), s2.size());
.....
}

我在尝试使用以下代码解密文件时出错

   void Decrypt(std::string encrypted_file,SecByteBlock key,SecByteBlock iv,string decrypted_file) {


        string recovered;
     try
     {
          // Read the encrypted file contents to a string as binary data.
      std::ifstream infile(encrypted_file.c_str(), std::ios::binary);
      const std::string cipher_text((std::istreambuf_iterator<char>(infile)),
                                     std::istreambuf_iterator<char>());
      infile.close();


      CBC_Mode< CryptoPP::AES >::Decryption d;
        d.SetKeyWithIV( key, key.size(), iv );

解密错误: StreamTransformationFilter:发现无效的 PKCS #7 块填充

这意味着我在解密过程中有不同的密钥。为什么会发生这种情况,以及是否有人可以帮助解决此问题。

【问题讨论】:

  • 我认为我们需要查看更多代码,包括如何存储和加载密钥。根据 sn-ps,您似乎将二进制数据视为字符串:string s1=argv[7];。这通常效果不佳。另见Null character in encrypted dataHaving trouble decrypting a well-formed cipher text using Crypto++AES padding and writing the ciphertext to a disk file
  • “这意味着我在解密过程中有不同的密钥” - 没有必要。您可能只是在解密时使用了错误的参数。我们绝对应该看到更多您的代码。尤其是加密部分。
  • 感谢您的回复,我已经用加密部分完整代码更新了问题。 @jww,我认为问题出在那部分;但我无法理解如何将字符串转换为 SecByteBlock,感谢您提供的示例。

标签: c++ encryption crypto++


【解决方案1】:

如果用于解密的密钥与用于加密的密钥不同,则会发生这种情况。

在解密过程中,在PKCS#7模式下,在解密最后一个16字节的块后,为了知道消息的原始长度(不一定是16字节的倍数),会检查填充字节: 最后一个字节应该是0x01,或者最后两个字节应该等于0x02,或者最后三个字节应该等于0x03,...当解密密钥与加密密钥不同时,填充字节为未正确解密,这意味着解密时出现 PKCS#7 块填充错误。

【讨论】:

    【解决方案2】:

    我将 CBC_Mode 更改为其他模式,ODB_Mode 为我工作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-09
      • 1970-01-01
      • 1970-01-01
      • 2014-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多