Шифрование / дешифрование файла построчно?

Я довольно новичок в шифровании, и я пытаюсь заставить работать построчный шифратор; Мне нужно иметь возможность добавлять зашифрованные строки к файлу во время работы приложения, а не просто один большой массив шифрования и сохранения. Хотя у меня с ним время зверя. Вот мой шифратор, бессовестно украденный после нескольких неудачных попыток:


class Encryption
    {
        private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c };

        public static byte[] Encrypt(byte[] plain, string password)
        {
            MemoryStream memoryStream;
            CryptoStream cryptoStream;
            Rijndael rijndael = Rijndael.Create();
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT);
            rijndael.Key = pdb.GetBytes(32);
            rijndael.IV = pdb.GetBytes(16);
            memoryStream = new MemoryStream();
            cryptoStream = new CryptoStream(memoryStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write);
            cryptoStream.Write(plain, 0, plain.Length);
            cryptoStream.FlushFinalBlock();
            cryptoStream.Close();
            return memoryStream.ToArray();
        }

        public static byte[] Decrypt(byte[] cipher, string password)
        {
            MemoryStream memoryStream;
            CryptoStream cryptoStream;
            Rijndael rijndael = Rijndael.Create();
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT);
            rijndael.Key = pdb.GetBytes(32);
            rijndael.IV = pdb.GetBytes(16);
            memoryStream = new MemoryStream();
            cryptoStream = new CryptoStream(memoryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write);
            cryptoStream.Write(cipher, 0, cipher.Length);
            cryptoStream.FlushFinalBlock();
            cryptoStream.Close();
            return memoryStream.ToArray();
        }
    }

А вот фиктивная функция, показывающая, как я пытаюсь это сделать:

       private void EncryptFile (строковый путь к файлу, строковый выходной путь, строковый пароль)
        {
            FileInfo fileInfo = new FileInfo(filepath); строка filename = fileInfo.Name; строка fullpath = outputPath + "\\" + имя файла;

            BinaryWriter writer = новый BinaryWriter(File.OpenWrite(полный путь), Encoding.ASCII);

            /// Два метода, которые я попробовал здесь:
            /// 1. Нужный метод: шифровать построчно - я предполагал, что смогу генерировать /// несколько блоков данных и расшифровывать их позже. Это не работает //string[] lines = File.ReadAllLines(filepath);

            /// 2. Просто прочитайте все это, зашифруйте и напишите одним махом. строка строки = File.ReadAllText(filepath);

            //foreach(строка строка в строках)
            {
                byte[] bytes = Encoding.ASCII.GetBytes(line);
                byte[] encoded = Encryption.Encrypt(байты, пароль);

                writer.Write(кодируются);
                writer.Flush();
            }

            writer.Close();
        }



        private void DecryptFile(строка filepath, строка outputPath, строка пароля)
        {
            FileInfo fileInfo = new FileInfo(filepath); строка filename = fileInfo.Name; строка fullpath = outputPath + "\\" + имя файла;

            StreamWriter writer = новый StreamWriter(полный путь, ложь, Encoding.UTF8);

            byte[] bytes = File.ReadAllBytes(filepath);

            /// Вот метод, который работает в данный момент для расшифровки; просто /// захватить все данные и расшифровать их одним махом.

            byte[] decrypted = Encryption.Decrypt(байты, пароль); строка s = Encoding.ASCII.GetString(расшифрованный);

                writer.Write(ы);
            writer.Flush();


            /// Я пробовал несколько вещей, чтобы расшифровать построчно, /// ни одна из которых не работает. Это вылетает из-за того, что заполнение /// неверно.  

            /*
            int index = 0;
            int count = 32;

            while (index 

Я не совсем уверен, что я должен делать больше. Я бродил, ковыряясь в вещах и читая примеры в Интернете, но все они, похоже, как зашифровать целый файл или просто зашифровать часть данных и ничего не делать с этим, кроме как сразу же расшифровать их снова. Как мне вести построчную запись?

1 ответ

Вместо того, чтобы программировать это для вас, я дам вам схему, которую вы могли бы реализовать.

Если у вас есть шифрование для каждой строки, я полагаю, вы хотите иметь возможность дешифровать также и для каждой строки. Обратите внимание, что "линия" - довольно неудобный термин для компьютера. Это просто набор символов, оканчивающихся каким-то ограничителем строки. Сами по себе символы кодируются с использованием определенной кодировки символов.

Кроме того, я сделаю следующие предположения:

  • зашифрованный текст должен быть представлен в строках, что означает, что байты необходимо преобразовать из двоичного в символ (с использованием кодировки);
  • вы хотите использовать один ключ, оставаясь в безопасности;
  • вам не нужна защита целостности или аутентификация зашифрованного текста, только конфиденциальность.

Теперь идея проста:

  1. создать один ключ, используя функцию получения ключа на основе пароля;
  2. открыть текстовый файл для чтения (используя правильную кодировку символов);
  3. прочитать строку и снова преобразовать ее в байты (например, используя UTF-8);
  4. создать выходной поток, который создает байтовый массив внизу;
  5. создать случайный IV и записать его в байтовый массив (IV всегда имеет размер одного блока);
  6. создать криптопоток и подключить его к тому же выходному потоку;
  7. зашифровать закодированную строку;
  8. base 64 кодирует зашифрованные байты и следит за тем, чтобы он оставался в одной строке;
  9. записать закодированную, зашифрованную строку в новый текстовый файл.

Чтобы сделать обратное, выполните обратный процесс, хотя IV следует извлекать из байтов после декодирования base 64, и ключ, конечно, должен быть рассчитан с использованием того же метода, который использовался во время шифрования.

Другие вопросы по тегам