Как зашифровать и дешифровать .txt файл?

У меня имеется часть кода, которая занимается записью поступающих значений в текстовый файл программы:

public int writeData() {

            StreamWriter logStr = new StreamWriter(logPath, true);
            logStr.WriteLine(currentTime + "Calls are loaded"); // log information
            logStr.Close();
            return 1;

}

Также у меня есть функция для считывания и загрузки информации из того самого файла:

        protected void readContent()
        {

            this.content = File.ReadAllLines(logPath);

        }

Как реализовать шифрование файла на стадии сохранения(writeData function) и его же дешифрование на стадии чтения(readContent function)? Я очень далек от темы шифрования данных, потому обратился за помощью на форум


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

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

Например вот так с использованием AesManaged из System.Security.Cryptography.

class Program
{
    static void Main(string[] args)
    {
        string fileName = "file.txt";
        string text = "Hello World!";
        byte[] key = Enumerable.Range(0, 32).Select(x => (byte)x).ToArray(); // массив [ 0, 1, 2, ..., 31 ], для примера
        FileWriteAllText(fileName, text);
        Console.WriteLine("Файл создан. Нажми любую клавишу.");
        Console.ReadKey(true);
        EncryptFile(fileName, key);
        Console.WriteLine("Файл зашифрован. Нажми любую клавишу.");
        Console.ReadKey(true);
        DecryptFile(fileName, key);
        Console.WriteLine("Файл расшифрован.");
        Console.WriteLine(File.ReadAllText(fileName));
        Console.ReadKey(true);
    }

    private static string EncryptFile(string path, byte[] key)
    {
        string tmpPath = Path.GetTempFileName();
        using (FileStream fsSrc = File.OpenRead(path))
        using (AesManaged aes = new AesManaged() { Key = key })
        using (FileStream fsDst = File.Create(tmpPath))
        {
            fsDst.Write(aes.IV);
            using (CryptoStream cs = new CryptoStream(fsDst, aes.CreateEncryptor(), CryptoStreamMode.Write, true))
            {
                fsSrc.CopyTo(cs);
            }
        }
        File.Delete(path);
        File.Move(tmpPath, path);
    }

    private static string DecryptFile(string path, byte[] key)
    {
        string tmpPath = Path.GetTempFileName();
        using (FileStream fsSrc = File.OpenRead(path))
        {
            byte[] iv = new byte[16];
            fsSrc.Read(iv);
            using (AesManaged aes = new AesManaged() { Key = key, IV = iv})
            using (CryptoStream cs = new CryptoStream(fsSrc, aes.CreateDecryptor(), CryptoStreamMode.Read, true))
            using (FileStream fsDst = File.Create(tmpPath))
            {
                cs.CopyTo(fsDst);
            }
        }
        File.Delete(path);
        File.Move(tmpPath, path);
    }
}

Вывод в консоль

Файл создан. Нажми любую клавишу.
Файл зашифрован. Нажми любую клавишу.
Файл расшифрован.
Hello World!
→ Ссылка
Автор решения: Ivan P.

Microsoft предложила немного другой способ шифровать и расшифровать файлы:

Шифрование

https://learn.microsoft.com/en-us/dotnet/standard/security/encrypting-data

Чтобы не потерялось, скопирую сюда:

using System.Security.Cryptography;

try
{
    using (FileStream fileStream = new("TestData.txt", FileMode.OpenOrCreate))
    {
        using (Aes aes = Aes.Create())
        {
            byte[] key =
            {
                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
            };
            aes.Key = key;

            byte[] iv = aes.IV;
            fileStream.Write(iv, 0, iv.Length);

            using (CryptoStream cryptoStream = new(
                fileStream,
                aes.CreateEncryptor(),
                CryptoStreamMode.Write))
            {
                // By default, the StreamWriter uses UTF-8 encoding.
                // To change the text encoding, pass the desired encoding as the second parameter.
                // For example, new StreamWriter(cryptoStream, Encoding.Unicode).
                using (StreamWriter encryptWriter = new(cryptoStream))
                {
                    encryptWriter.WriteLine("Hello World!");
                }
            }
        }
    }

    Console.WriteLine("The file was encrypted.");
}
catch (Exception ex)
{
    Console.WriteLine($"The encryption failed. {ex}");
}

В этом примере рассматриваются возможность применения кодировок и более современный синтаксис

Дешифрование

https://learn.microsoft.com/en-us/dotnet/standard/security/decrypting-data

using System.Security.Cryptography;

try
{
    using (FileStream fileStream = new("TestData.txt", FileMode.Open))
    {
        using (Aes aes = Aes.Create())
        {
            byte[] iv = new byte[aes.IV.Length];
            int numBytesToRead = aes.IV.Length;
            int numBytesRead = 0;
            while (numBytesToRead > 0)
            {
                int n = fileStream.Read(iv, numBytesRead, numBytesToRead);
                if (n == 0) break;

                numBytesRead += n;
                numBytesToRead -= n;
            }

            byte[] key =
            {
                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
            };

            using (CryptoStream cryptoStream = new(
               fileStream,
               aes.CreateDecryptor(key, iv),
               CryptoStreamMode.Read))
            {
                // By default, the StreamReader uses UTF-8 encoding.
                // To change the text encoding, pass the desired encoding as the second parameter.
                // For example, new StreamReader(cryptoStream, Encoding.Unicode).
                using (StreamReader decryptReader = new(cryptoStream))
                {
                    string decryptedMessage = await decryptReader.ReadToEndAsync();
                    Console.WriteLine($"The decrypted original message: {decryptedMessage}");
                }
            }
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine($"The decryption failed. {ex}");
}

Кроме того, тут используются StreamReader и StreamWriter, а их можно в теории использовать при сериализации

→ Ссылка