3

I am attempting to decrypt a file to ONLY the process memory. I do not want the actual file to be sent to plain text as it will be storing sensitive data. I do not want the raw text sitting on the system at all.

I am currently testing with a eula file in C:\ BUT get the same issue no matter what file I use.

I am using AES with salting. Decrypting the file does work as right now I am dumping the decrypted data to the text document but when I am attempting to compile the decrpytedBytes into a string, it only outputs 3 characters that are non-existent in that order anywhere inside of the document.

https://i.stack.imgur.com/0531F.png

Those 2 characters show up while using System.Text.Encoding.UTF8.GetString(bytesDecrypted, 0, bytesDecrypted.Length) to compile the byte array to a string.

I have attempted just a basic .ToString() but that returned System.Byte[] and nothing more

https://i.stack.imgur.com/Q3Nrc.png

While using var str = System.Text.Encoding.Default.GetString(bytesDecrypted) it only outputs ÿþ*

https://i.stack.imgur.com/9H59L.png

Here is the code I am using for encryption and decryption

 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;
 }

If you have any idea/clues on how I could manage to get this working I would greatly appreciate it!

Markus Safar
  • 6,324
  • 5
  • 28
  • 44
Tyson
  • 45
  • 9
  • I just copied your code and testet it, works fine for me... – Markus Safar Nov 02 '18 at 21:28
  • The `ÿþ*` looks like a UTF-16 LE BOM (two bytes 0xFE 0xFF), which would mean that the original file was in UTF-16/UCS 2 Unicode. I really don't know what you do in your code with the decrypted byte array, but try the UNICODE encoding to decode your byte blob... –  Nov 02 '18 at 21:28
  • @MarkusSafar Writing the data back into the file works fine, however trying to load the decrypted data into a byte array and not decrypting the file is not working. Did you load the byte array as a string or just decrypt the file? – Tyson Nov 02 '18 at 21:32
  • 2
    @elgonzo Changing it to unicode works! Thank you so much! – Tyson Nov 02 '18 at 21:33
  • I directly encrypted a file and afterwards decrypted this file into a new one. As this works fine I guess you have some issue with your code page, I am sure you need to change it to unicode (as elgonzo suggested) ;-) – Markus Safar Nov 02 '18 at 21:34
  • @Thaisen, you should not post your answer within the question, instead encourage elgonzo that he posts the answer and then mark it as the correct one. – Markus Safar Nov 02 '18 at 21:36
  • I don't use Stack overflow much, but I will see if he is willing to do that :D @elgonzo – Tyson Nov 02 '18 at 21:38
  • 1
    @MarkusSafar, i am writing an answer. I am currently watching Starcraft2 WCS Stats vs. Special. I'll write my answer in the break between matches, so it will take some time ;-) –  Nov 02 '18 at 21:39
  • 1
    @elgonzo, hahaha - I see, enjoy ;-) – Markus Safar Nov 02 '18 at 21:39

2 Answers2

3

You used the incorrect encoding to to decode your decrypted byte array. The encoding of the original text file is most likely Unicode/UTF-16. Thus, use the Encoding.Unicode encoding to decode the decrypted byte array back to text:

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



Some background information

So, what made me think that the encoding of the original text file is UTF-16/Unicode? This information from the question gives a crucial hint:

While using var str = System.Text.Encoding.Default.GetString(bytesDecrypted) it only outputs ÿþ*

Note the ÿþ. This is how an UTF-16 LE BOM (*) appears if text data having this BOM is decoded/shown using the ISO/IEC 8859-1 (or CP-1252) code page, which often is the default code page used in many (english/non-localized) Windows installations.

(*) The UTF-16 LE BOM (UTF-16 Little-Endian Byte Order Mark) are two bytes 0xFF,0xFE. To learn more about what BOMs are and what their purpose is, i suggest this Wikipedia article: https://en.wikipedia.org/wiki/Byte_order_mark

-1

Found this answer that I think applies to your issue. Pay special attention to "encryptedData = output.ToArray();"

Reading from a cryptostream to the end of the stream

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();
    }
}
P. Roe
  • 2,077
  • 1
  • 16
  • 23
  • 1
    Turns out I was using the wrong data type for loading it. Changing UTF8 to Unicode did end up working for me. Thank you for the input tho – Tyson Nov 02 '18 at 21:36