Шифрование / дешифрование файла построчно?
Я довольно новичок в шифровании, и я пытаюсь заставить работать построчный шифратор; Мне нужно иметь возможность добавлять зашифрованные строки к файлу во время работы приложения, а не просто один большой массив шифрования и сохранения. Хотя у меня с ним время зверя. Вот мой шифратор, бессовестно украденный после нескольких неудачных попыток:
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 ответ
Вместо того, чтобы программировать это для вас, я дам вам схему, которую вы могли бы реализовать.
Если у вас есть шифрование для каждой строки, я полагаю, вы хотите иметь возможность дешифровать также и для каждой строки. Обратите внимание, что "линия" - довольно неудобный термин для компьютера. Это просто набор символов, оканчивающихся каким-то ограничителем строки. Сами по себе символы кодируются с использованием определенной кодировки символов.
Кроме того, я сделаю следующие предположения:
- зашифрованный текст должен быть представлен в строках, что означает, что байты необходимо преобразовать из двоичного в символ (с использованием кодировки);
- вы хотите использовать один ключ, оставаясь в безопасности;
- вам не нужна защита целостности или аутентификация зашифрованного текста, только конфиденциальность.
Теперь идея проста:
- создать один ключ, используя функцию получения ключа на основе пароля;
- открыть текстовый файл для чтения (используя правильную кодировку символов);
- прочитать строку и снова преобразовать ее в байты (например, используя UTF-8);
- создать выходной поток, который создает байтовый массив внизу;
- создать случайный IV и записать его в байтовый массив (IV всегда имеет размер одного блока);
- создать криптопоток и подключить его к тому же выходному потоку;
- зашифровать закодированную строку;
- base 64 кодирует зашифрованные байты и следит за тем, чтобы он оставался в одной строке;
- записать закодированную, зашифрованную строку в новый текстовый файл.
Чтобы сделать обратное, выполните обратный процесс, хотя IV следует извлекать из байтов после декодирования base 64, и ключ, конечно, должен быть рассчитан с использованием того же метода, который использовался во время шифрования.