AES填充并将密文写入磁盘文件 [英] AES padding and writing the ciphertext to a disk file

查看:109
本文介绍了AES填充并将密文写入磁盘文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个字符串,该字符串使用Crypto ++在C ++中使用以下方法加密:

I have a string which I encrypt with the following mehtod in C++ using Crypto++:

std::ifstream t(filename); //File to be encrypt
std::stringstream buffer;
buffer << t.rdbuf();

ofstream combined_file2(filename2); //Encrypted file
combined_file2 << encrypt(buffer.str());

string encrypt(string data)
{
  // Key and IV setup
  std::string key = "0123456789abcdef";
  std::string iv = "aaaaaaaaaaaaaaaa";

  //Alternative
  //byte key[CryptoPP::AES::DEFAULT_KEYLENGTH], iv[CryptoPP::AES::BLOCKSIZE];
  //memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH);
  //memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE);

  std::string plaintext = data;
  std::string ciphertext;

  // Create Cipher Text
  CryptoPP::AES::Encryption aesEncryption((byte *)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH);
  CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, (byte *)iv.c_str());

  //Alternative
  //CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH);
  //CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv);

  CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(ciphertext));
  stfEncryptor.Put(reinterpret_cast<const unsigned char*>(plaintext.c_str()), plaintext.length() + 1);
  stfEncryptor.MessageEnd();

  return ciphertext;
}

当我尝试在C#应用程序中解密文件时,收到消息,数据长度无效.我认为字节数组的长度不是16的倍数,所以我得到了错误.我尝试使用填充,但无法正常工作.

When I try to decrypt the file in my C# Application, I get the message, that the length of the data is invalid. I think that the lenght of th byte array isn't a multiple of 16, so I get the error. I try to use a padding, but it is not working right.

这是我解密文件的方式:

Here is how I decrypt the file:

string plaintext = Decrypt(File.ReadAllBytes(path));

private static string Decrypt(byte[] cipherText)
{
   if (cipherText == null || cipherText.Length <= 0)
       throw new ArgumentNullException("cipherText");
   byte[] Key = GetBytes(ConfigurationManager.AppSettings["aes_key"]);
   byte[] IV = GetBytes(ConfigurationManager.AppSettings["aes_iv"]);

   // Declare the string used to hold the decrypted text.
   string plaintext = null;

   // Create an RijndaelManaged object with the specified key and IV.
   using (RijndaelManaged rijAlg = new RijndaelManaged())
   {
     rijAlg.Key = Key;
     //rijAlg.IV = IV;
     //for testing                
     rijAlg.IV = new byte[] { 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97 };

    // Create a decrytor to perform the stream transform.
    ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

    // Create the streams used for decryption.
    using (MemoryStream msDecrypt = new MemoryStream(cipherText))
    {
      using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
      {
        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
        {
          // Read the decrypted bytes from the decrypting stream
          // and place them in a string.
          plaintext = srDecrypt.ReadToEnd();
        }
      }
    }
  }
  return plaintext;
}

我该如何解决该问题?是否有任何功能可以执行填充,或者填充是错误的方法?

How can I solve the problem? Is there any function to do the padding, or maybe padding is the wrong way?

推荐答案

基于评论:

在C ++中,我保存了一个文件Combined_file2<<加密(buffer.str());我 在我的C#程序字符串中读取了plaintext = 解密(File.ReadAllBytes(path));

In C++ I save a file combined_file2 << encrypt(buffer.str()); which I read in my C# program string plaintext = Decrypt(File.ReadAllBytes(path));

我不认为嵌入式NULL会导致encrypt函数引起问题,因为它返回了string,并且其中包含明确的长度.

I don't think embedded NULLs is causing problems from the encrypt function since its returning a string, and that includes an explicit length.

但是,嵌入式NULL以及在C ++中将文件写入磁盘(或在C#中从磁盘读取文件)的方式将是一个问题,因为它将在第一个嵌入式NULL处停止:combined_file2 << encrypt(buffer.str()).

However, an embedded NULL and the way the file is being written to disk in C++ (or read from disk in C#) will be a problem since this will stop at the first embedded NULL: combined_file2 << encrypt(buffer.str()).

以下内容可能会有所帮助:

Perhaps something like the following would be helpful:

StringSource ss(ciphertext, true /*pumpAll*/);
FileSink fs("my-encrypted-file.bin", true /*binary*/);
ss.TransferTo(fs);

如果使用的是C ++流,则对流对象使用write方法:

If you are using a C++ stream, then use the write method on the stream object:

ofstream combined_file2;
...
combined_file2.write(ciphertext.data(), ciphertext.size());

这篇关于AES填充并将密文写入磁盘文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆