Как добавить текст в зашифрованный файл, и прочитать и удалить текст перед расшифровкой

Мне нужно добавить какой-нибудь текст (в файл, любой не только текстовый, размер файла от 1 кб до 100 мб) как в начало и по желанию в конец зашифрованного файла, как это можно реализовать в этих методах?

Метод шифрования:

public static void AES_Encrypt(string inputFile, string password)
{
   try
   {
      byte[] passBytes = Encoding.UTF8.GetBytes(password);
      byte[] saltBytes = new byte[12];
 
      using (MemoryStream tempStream = new MemoryStream())
      {
         using (var inputFileStream = new FileStream(inputFile, FileMode.Open))
         inputFileStream.CopyTo(tempStream);
         tempStream.Position = 0;
 
         using (var outFileStream = new FileStream(inputFile, FileMode.Create))
         using (var rijndaelManaged = new RijndaelManaged())
         {
           rijndaelManaged.KeySize = 256;
           rijndaelManaged.BlockSize = 256;
           using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(passBytes, saltBytes, 1000))
           {
              rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
              rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
           }
           rijndaelManaged.Mode = CipherMode.CBC;
           using (var cryptoStream = new CryptoStream(outFileStream, rijndaelManaged.CreateEncryptor(), CryptoStreamMode.Write))
           {
               tempStream.CopyTo(cryptoStream);
           }
         }
      }
    }
    catch  { }
}

Метод расшифровки:

public static void AES_Decrypt(string inputFile, string password)
{
      try
      {
         byte[] passBytes = Encoding.UTF8.GetBytes(password);
         byte[] saltBytes = new byte[8];
 
         using (MemoryStream tempStream = new MemoryStream())
         {
             using (var inputFileStream = new FileStream(inputFile, FileMode.Open))
             inputFileStream.CopyTo(tempStream);
             tempStream.Position = 0;
 
             using (var outFileStream = new FileStream(inputFile, FileMode.Create))
             using (var rijndaelManaged = new RijndaelManaged())
             {
               rijndaelManaged.KeySize = 256;
               rijndaelManaged.BlockSize = 256;
               using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(passBytes, saltBytes, 1000))
               {
                 rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
                 rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
               }
               rijndaelManaged.Mode = CipherMode.CBC;
               using (var cryptoStream = new CryptoStream(tempStream, rijndaelManaged.CreateDecryptor(), CryptoStreamMode.Read))
               {
                  cryptoStream.CopyTo(outFileStream);
               }
             }
           }
        }
     }
     catch { }
}

Ответы (1 шт):

Автор решения: aepot

Не вдаваясь в подробности, вот решение с записью сигнатуры в начало файла.

private static readonly byte[] signature = Encoding.UTF8.GetBytes("TEXT");

public static void AES_Encrypt(string inputFile, string password)
{
    try
    {
        byte[] passBytes = Encoding.UTF8.GetBytes(password);
        byte[] saltBytes = new byte[12];

        using (MemoryStream tempStream = new MemoryStream())
        {
            using (var inputFileStream = new FileStream(inputFile, FileMode.Open))
                inputFileStream.CopyTo(tempStream);
            tempStream.Position = 0;

            using (var outFileStream = new FileStream(inputFile, FileMode.Create))
            using (var rijndaelManaged = new RijndaelManaged())
            {
                outFileStream.Write(signature, 0, signature.Length);
                rijndaelManaged.KeySize = 256;
                rijndaelManaged.BlockSize = 256;
                using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(passBytes, saltBytes, 1000))
                {
                    rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
                    rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
                }
                rijndaelManaged.Mode = CipherMode.CBC;
                using (var cryptoStream = new CryptoStream(outFileStream, rijndaelManaged.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    tempStream.CopyTo(cryptoStream);
                }
            }
        }
    }
    catch { }
}

public static void AES_Decrypt(string inputFile, string password)
{
    try
    {
        byte[] passBytes = Encoding.UTF8.GetBytes(password);
        byte[] saltBytes = new byte[12];

        using (MemoryStream tempStream = new MemoryStream())
        {
            using (var inputFileStream = new FileStream(inputFile, FileMode.Open))
                inputFileStream.CopyTo(tempStream);
            tempStream.Position = 0;
            byte[] testSignature = new byte[signature.Length];
            int bytesRead = tempStream.Read(testSignature, 0, signature.Length);
            if (bytesRead != signature.Length || !testSignature.SequenceEqual(signature))
            {
                return; // сигнатура не найдена
            }

            using (var outFileStream = new FileStream(inputFile, FileMode.Create))
            using (var rijndaelManaged = new RijndaelManaged())
            {
                rijndaelManaged.KeySize = 256;
                rijndaelManaged.BlockSize = 256;
                using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(passBytes, saltBytes, 1000))
                {
                    rijndaelManaged.Key = rfc2898DeriveBytes.GetBytes(rijndaelManaged.KeySize / 8);
                    rijndaelManaged.IV = rfc2898DeriveBytes.GetBytes(rijndaelManaged.BlockSize / 8);
                }
                rijndaelManaged.Mode = CipherMode.CBC;
                using (var cryptoStream = new CryptoStream(tempStream, rijndaelManaged.CreateDecryptor(), CryptoStreamMode.Read))
                {
                    cryptoStream.CopyTo(outFileStream);
                }
            }
        }
    }
    catch { }
}

Потенциальные проблемы:

  • Файл полностью читается в память при расшифровке и шифровке, могут возникнуть проблемы с OutOfMemoryException при работе с большими файлами.
  • Данный в методах try-catch полностью гасит все исключения, то есть вы никогда не узнаете, если при работе с файлом возникла ошибка. Так делать не рекомендуется.
  • В исходных методах несоответстве длины массива соли, то есть пара методов не рабочая, я исправил.
→ Ссылка