C # пытается расшифровать файл только для обработки памяти - PullRequest
0 голосов
/ 02 ноября 2018

Я пытаюсь расшифровать файл ТОЛЬКО в память процесса. Я не хочу, чтобы фактический файл отправлялся в виде простого текста, поскольку он будет хранить конфиденциальные данные. Я не хочу, чтобы необработанный текст вообще сидел в системе.

В настоящее время я тестирую файл eula в C: \ BUT, но получаю ту же проблему независимо от того, какой файл я использую.

Я использую AES с засолкой. Расшифровка файла работает так, как сейчас. Я выгружаю расшифрованные данные в текстовый документ, но когда я пытаюсь скомпилировать decrpytedBytes в строку, он выводит только 3 символа, которые не существуют в указанном порядке в любом месте документа.

https://i.imgur.com/WAQ2njB.png

Эти 2 символа отображаются при использовании System.Text.Encoding.UTF8.GetString(bytesDecrypted, 0, bytesDecrypted.Length) для компиляции массива байтов в строку.

Я попытался только простой .ToString(), но вернул System.Byte[] и ничего более

https://i.imgur.com/Gg5Et72.png

При использовании var str = System.Text.Encoding.Default.GetString(bytesDecrypted) выводятся только ÿþ *

https://i.imgur.com/94hMuB3.png

Вот код, который я использую для шифрования и дешифрования

 public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
 {
     byte[] encryptedBytes = null;
     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;
     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;
 }

 public void EncryptFile(string file, string fileEncrypted, string password)
 {
     byte[] bytesToBeEncrypted = File.ReadAllBytes(file);
     byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

     passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

     byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);

     File.WriteAllBytes(fileEncrypted, bytesEncrypted);
     listBox1.Items.Add("Enrypted the file");
 }

 public void DecryptFile(string fileEncrypted, string file, string password)
 {
     byte[] bytesToBeDecrypted = File.ReadAllBytes(fileEncrypted);
     byte[] passwordBytes = Encoding.UTF8.GetBytes(password);

     passwordBytes = SHA256.Create().ComputeHash(passwordBytes);

     byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);

     listBox1.Items.Add("Attempting Decryption");
     File.WriteAllBytes(file, bytesDecrypted);

     var str = System.Text.Encoding.Default.GetString(bytesDecrypted);

     richTextBox1.Text = str;
 }

Если у вас есть идеи / подсказки о том, как мне это удалось сделать, я был бы очень признателен!

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Вы использовали неправильную кодировку для декодирования вашего расшифрованного массива байтов. Кодировка исходного текстового файла, скорее всего, Unicode / UTF-16. Таким образом, используйте кодировку Encoding.Unicode для декодирования расшифрованного массива байтов обратно в текст:

var str = System.Text.Encoding.Unicode.GetString(bytesDecrypted);



Некоторая справочная информация

Итак, что заставило меня подумать, что кодировка исходного текстового файла - UTF-16 / Unicode? Эта информация из вопроса дает важный намек:

При использовании var str = System.Text.Encoding.Default.GetString (bytesDecrypted) выводятся только ÿþ *

Обратите внимание на ÿþ. Вот как появляется UTF-16 LE BOM (*), если текстовые данные, имеющие эту BOM, декодируются / отображаются с использованием кодовой страницы ISO / IEC 8859-1 (или CP-1252), которая часто является кодовой страницей по умолчанию, используемой во многих (английский / нелокализованный) Windows установки.

(*) LE UTF-16 LE (UTF-16 Little-Endian Byte Order Mark) - два байта 0xFF, 0xFE. Чтобы узнать больше о том, что такое спецификации и какова их цель, я предлагаю эту статью в Википедии: https://en.wikipedia.org/wiki/Byte_order_mark

0 голосов
/ 03 ноября 2018

Нашел этот ответ, который, я думаю, относится к вашей проблеме. Обратите особое внимание на "encryptedData = output.ToArray ();"

Чтение из криптопотока до конца потока

byte[] encryptedData;
rijCrypto.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
rijCrypto.KeySize = 256;

using (var input = new MemoryStream(Encoding.Unicode.GetBytes(tempData)))
using (var output = new MemoryStream())
{
    var encryptor = rijCrypto.CreateEncryptor();

    using (var cryptStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
    {
        var buffer = new byte[1024];
        var read = input.Read(buffer, 0, buffer.Length);
        while (read > 0)
        {
            cryptStream.Write(buffer, 0, read);
            read = input.Read(buffer, 0, buffer.Length);
        }
        cryptStream.FlushFinalBlock();
        encryptedData = output.ToArray();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...