使用AES解密时,前16个字节已损坏

First 16 bytes corrupted while decrypting using AES

本文关键字:16个 字节 已损坏 AES 解密 使用      更新时间:2023-10-16

我使用openssl编码了一个文本文件,如下所示:

openssl enc -nosalt -aes-128-cbc -k mypass -in "test.txt" -out "test_enc.txt" -p

并且它返回密钥和iv如下:

key=A029D0DF84EB5549C641E04A9EF389E5
iv =A10CE9C4682486F8622F2F18E7291367

这是我用来解密文件的代码:

 int main() {
      streampos size;
      char * indata;
      ifstream file ("test_enc.txt", ios::in|ios::binary|ios::ate);
      ofstream outfile ("test_decoded.txt",std::ofstream::binary);
      if (file.is_open())
      {
        size = file.tellg();
        indata = new char [size];
        file.seekg (0, ios::beg);
        file.read (indata, size);
        file.close();
        unsigned char* outdata=new unsigned char [size];
        unsigned char ckey[] = "xA0x29xD0xDFx84xEBx55x49xC6x41xE0x4Ax9ExF3x89xE5";
        unsigned char ivec[] = "xA1x0CxE9xC4x68x24x86xF8x62x2Fx2Fx18xE7x29x13x67";
        AES_KEY key;
        AES_set_decrypt_key(ckey, 256, &key);
        AES_cbc_encrypt((unsigned char*) indata, outdata, size, &key, ivec, AES_DECRYPT);

        outfile.write ((char*) outdata,size);
        delete[] indata;
        delete[] outdata;
      }
      else{
          cout << "Unable to open file";
          cerr << "Error: " << strerror(errno);
      }
      outfile.close();
      file.close();
      return 0;
}

这个代码运行得很好。然而,当我在编码时使用salt时,如以下命令所示:

openssl enc -aes-128-cbc -k mypass -in "test.txt" -out "test_enc.txt" -p

并适当地替换代码中的密钥和ivec,整个文件被正确解密,但前16个字节!我从其他有类似问题的帖子中了解到,我知道iv值是错误的,但我不知道什么应该是正确的iv值。我只使用加密后返回的密钥和iv值,也没有考虑salt值(实际上我不知道如何)。正确的iv值应该是多少?

从您的问题症状来看,在我看来,您的以下逻辑可能正在释放内存,而稍后程序中的代码正在读取内存。这导致了这种情况。通常情况下,这是因为在释放内存后,堆管理器通常会为自己的使用写入一些内务管理信息。

关键是我们不应该在释放内存后使用它,因为它是悬空的。

//Allocate the memory
unsigned char* outdata=new unsigned char [size];
// It appears to me that here the outdata is getting freed. I do not see anywhere
// else this memory is getting freed.
AES_cbc_encrypt((unsigned char*) indata, outdata, size, &key, ivec, AES_DECRYPT);
// Due to this, while accessing it we are seeing the 16 bytes corrupted.
outfile.write ((char*) outdata,size);

您可以使用任何动态工具来识别此类问题。

我也遇到了类似的问题。在我的案例中,问题是传递给AES_cbc_encrypt的IV在算法执行期间被修改。为了保存IV的内容,我以前不得不保存一份副本。

这里描述了一个类似问题的解决方案。