R. B. Krish Ответов: 1

Как зашифровать папку с большими файлами с помощью алгоритма AES на языке Си#


Привет кодовые товарищи по проекту,

У меня серьезные проблемы с шифрованием и дешифрованием. То, что у меня есть, - это папка, которая может быть разных размеров, но может иметь объем 100 ГБ или около того.

Мой проект нужен:
Необходимость заключается в том, что при выходе из системы созданная мной служба windows должна зашифровать папку(то есть папку со 100 ГБ данных). И когда я снова войду в систему, он должен расшифровать его и сделать папку пригодной для использования.

Итак, вот моя проблема:
У меня прямо сейчас есть метод, который шифрует и расшифровывает файлы внутри папки в циклическом формате. Так что просто представьте, что у меня есть 100 ГБ или выше в папке, когда мы выходим из системы или входим в нее. Система может зависнуть с таким большим количеством данных.

Чего я хочу от вас ребята:
Я не прошу у вас полного кода, ребята. Мне просто нужна помощь.

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

Я ищу, чтобы сделать это программное обеспечение похожим на BITLOCKER. Моя служба должна легко обрабатывать большие файлы.

Что я уже пробовал:

Я попробовал следующий код:

protected void enCrypt(string filePath, string passWord)
        {
            //File.SetAttributes(filePath, FileAttributes.Normal);

            byte[] filestobeEncrypted = File.ReadAllBytes(filePath);
            byte[] passwordBytes = Encoding.UTF8.GetBytes(passWord);
            passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

            byte[] bytesEncrypted = AES_Encrypt(filestobeEncrypted, passwordBytes);
            File.WriteAllBytes(filePath, bytesEncrypted);
        }

        protected void deCrypt(string filePath, string passWord)
        {
            //File.SetAttributes(filePath, FileAttributes.Normal);

            byte[] filestobeDecrypted = File.ReadAllBytes(filePath);
            byte[] passwordBytes = Encoding.UTF8.GetBytes(passWord);
            passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

            byte[] bytesDecrypted = AES_Decrypt(filestobeDecrypted, passwordBytes);
            File.WriteAllBytes(filePath, bytesDecrypted);
        }

        public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
        {
            byte[] encryptedBytes = null;

            // Set your salt here, change it to meet your flavor:
            // The salt bytes must be at least 8 bytes.
            byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            using (MemoryStream ms = new MemoryStream())
            {
                using (RijndaelManaged AES = new RijndaelManaged())
                {
                    AES.KeySize = 256;
                    AES.BlockSize = 128;

                    var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                    AES.Key = key.GetBytes(AES.KeySize / 8);
                    AES.IV = key.GetBytes(AES.BlockSize / 8);

                    AES.Mode = CipherMode.CBC;

                    using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                        cs.Close();
                    }
                    encryptedBytes = ms.ToArray();
                }
            }

            return encryptedBytes;
        }

        public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
        {
            byte[] decryptedBytes = null;

            // Set your salt here, change it to meet your flavor:
            // The salt bytes must be at least 8 bytes.
            byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            using (MemoryStream ms = new MemoryStream())
            {
                using (RijndaelManaged AES = new RijndaelManaged())
                {
                    AES.KeySize = 256;
                    AES.BlockSize = 128;

                    var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                    AES.Key = key.GetBytes(AES.KeySize / 8);
                    AES.IV = key.GetBytes(AES.BlockSize / 8);

                    AES.Mode = CipherMode.CBC;

                    using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
                        cs.Close();
                    }
                    decryptedBytes = ms.ToArray();
                }
            }

            return decryptedBytes;
        }

CS2011

Я не уверен насчет папок, но если вы хотите зашифровать весь диск, вы можете использовать WMI (Win32_EncryptableVolume), который использует шифрование диска bit locker.

F-ES Sitecore

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

1 Ответов

Рейтинг:
2

#realJSOP

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

Вы не можете зашифровать папку. Вы должны зашифровать файлы внутри папки. Вот статья CP, в которой говорится о шифровании AES:

Алгоритмы шифрования FIPS и реализация AES в C# и SQL Server 2008[^]

Вы можете создать зашифрованный ZIP-файл, содержащий все файлы, но это займет много времени.

Я думаю, что лучшим решением было бы добавить сервер в сеть, на котором установлен bitlocker, скопировать папку на этот сервер, а затем добавить соответствующие разрешения пользователя для доступа. Не спрашивайте меня о деталях - я просто швыряю вещи в стену, чтобы посмотреть, что прилипнет.


R. B. Krish

Джон Симмонс, Спасибо за ваши предложения. Я этим займусь.