Aes дешифрация байтов c#

385
02 июля 2017, 12:17

Пытаюсь расшифровать зашифрованные байты алгоритмом AES, c#

byte[] buffer = new byte[1048576];
fsCrypt.Seek(0, SeekOrigin.Begin);
CryptoStream cryptoStream = new CryptoStream(fsCrypt, AES.CreateDecryptor(), CryptoStreamMode.Read);
read =1;
var len = Convert.ToInt32(fsCrypt.Length);
while (read > 0)
{
read = cryptoStream.Read(buffer, 0, len);
foreach (var m in buffer)
bytes.Add(m);
}

В результате выполнения кода в строке read = cryptoStream.Read(buffer, 0, len); получаю ошибку "Недопустимая длина данных для дешифрования.", при этом len = 4256. Можете подсказать в чем проблема ?

Пытался и с MemoryStream, но все та же ошибка

byte[] salt = new byte[32];
FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
fsCrypt.Seek(fsCrypt.Length - 32, SeekOrigin.Begin);
fsCrypt.Read(salt, 0, salt.Length);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Padding = PaddingMode.PKCS7;
AES.Mode = CipherMode.CFB;
int read;
byte[] buffer = new byte[1048576];
List < byte > bytes = new List < byte > ();
fsCrypt.Seek(0, SeekOrigin.Begin);
read = 1;
var len = Convert.ToInt32(fsCrypt.Length);
MemoryStream mem = new MemoryStream();
fsCrypt.CopyTo(mem);
mem.Position = 0;
using(CryptoStream cryptoStream = new CryptoStream(mem, AES.CreateDecryptor(), CryptoStreamMode.Read)) {
 //var buffer2 = new byte[len];
 read = cryptoStream.Read(buffer, 0, len);
 foreach(var m in buffer)
 bytes.Add(m);
}

Брал пример из http://stackoverflow.com/questions/27645527/aes-encryption-on-large-files

Как я шифрую:

byte[] salt = GenerateRandomSalt();

 //convert password string to byte arrray
 byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(password);
 //Set Rijndael symmetric encryption algorithm 71 246
 RijndaelManaged AES = new RijndaelManaged();
 AES.KeySize = 256;
 AES.BlockSize = 128;
 AES.Padding = PaddingMode.PKCS7;

 var key = new Rfc2898DeriveBytes(passwordBytes, salt, 50000);
 AES.Key = key.GetBytes(AES.KeySize / 8);
 AES.IV = key.GetBytes(AES.BlockSize / 8);
 AES.Mode = CipherMode.CFB;
 var kk = key.ToString();

 FileStream fsIn = new FileStream(inputFile, FileMode.Open);

 byte[] buffer = new byte[1048576];
 int read = 0;

 byte[] encrypted;
 using(MemoryStream msEncrypt = new MemoryStream()) {
  using(CryptoStream csEncrypt = new CryptoStream(msEncrypt, AES.CreateEncryptor(), CryptoStreamMode.Write)) {
   fsIn.Seek(0, SeekOrigin.Begin);
   while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0) {
    csEncrypt.Write(buffer, 0, read);
   }
   encrypted = msEncrypt.ToArray();
  }
 }
 fsIn.Seek(0, SeekOrigin.Begin);
 fsIn.Write(encrypted, 0, encrypted.Length);
 fsIn.Seek(fsIn.Length, SeekOrigin.Begin);
 fsIn.Write(salt, 0, salt.Length);
Answer 1

Вот вам полный пример шифровнии и дешифровании

 static void Main(string[] args)
    {
        try
        {
            string original = "This is my encription string";
            var myAes = Aes.Create();
            var encriptKey = myAes.Key;
            var encriptIV = myAes.IV;
            byte[] encrypted = EncriptDecryptClass.EncryptString(myAes, original, encriptKey, encriptIV);
            string decrypted = EncriptDecryptClass.DecryptString(myAes, encrypted, encriptKey, encriptIV);
            Console.WriteLine("Original:   {0}", original);
            Console.WriteLine("Enxription Text");
            foreach (var item in encrypted)
            {
                Console.Write(item);
            }
            Console.WriteLine("\n");
            Console.WriteLine("Decript Text: {0}", decrypted);
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: {0}", e.Message);
        }
    }
    public static class EncriptDecryptClass
    {
        public static byte[] EncryptString(Aes aesAlgoritm, string plainText, byte[] Key, byte[] IV)
        {
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");
            byte[] encrypted;
            ICryptoTransform encryptor = aesAlgoritm.CreateEncryptor(Key, IV);
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
            return encrypted;
        }
        public static string DecryptString(Aes aesAlgoritm, byte[] cipherText, byte[] Key, byte[] IV)
        {
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");
            string plaintext = null;
            ICryptoTransform decryptor = aesAlgoritm.CreateDecryptor(Key, IV);
            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
            return plaintext;
        }
    }  

И добавьте

using System.IO;
using System.Security.Cryptography;
Вот вам еще один способ для реализации этого

  static void Main(string[] args)
    {
        string original = "This is my encription string";
        string password = "myPassword";
        Console.WriteLine(original);
        var encript = CryptoClass.EncryptStringAES(original, password);
        using (StreamWriter write=new StreamWriter(@"C:\doc.txt"))
        {
            write.Write(encript);
        }
        Console.WriteLine(encript);
        string str;
        using (FileStream fs = new FileStream(@"C:\doc.txt", FileMode.Open))
        {
            using (StreamReader read = new StreamReader(fs))
            {
                str = read.ReadToEnd();
            }
        }
        var decript = CryptoClass.DecryptStringAES(str, password);
        Console.WriteLine(decript);
    }
    public class CryptoClass
    {
        public static byte[] GenerateRandomSalt()
        {
            byte[] data = new byte[32];
            using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
            {.
                for (int i = 0; i < 10; i++)
                {.
                    rng.GetBytes(data);
                }
            }
            return data;
        }
        private static byte[] _salt = GenerateRandomSalt();
        public static string EncryptStringAES(string plainText, string sharedSecret)
        {
            if (string.IsNullOrEmpty(plainText))
                throw new ArgumentNullException("plainText");
            if (string.IsNullOrEmpty(sharedSecret))
                throw new ArgumentNullException("sharedSecret");
            string outStr = null;                      
            RijndaelManaged aesAlg = null;         
            try
            {
                Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);
                aesAlg = new RijndaelManaged();
                aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int));
                    msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(plainText);
                        }
                    }
                    outStr = Convert.ToBase64String(msEncrypt.ToArray());
                }
            }
            finally
            {
                if (aesAlg != null)
                    aesAlg.Clear();
            }
            return outStr;
        }
        public static string DecryptStringAES(string cipherText, string sharedSecret)
        {
            if (string.IsNullOrEmpty(cipherText))
                throw new ArgumentNullException("cipherText");
            if (string.IsNullOrEmpty(sharedSecret))
                throw new ArgumentNullException("sharedSecret");
            RijndaelManaged aesAlg = null;
            string plaintext = null;
            try
            {
                Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);               
                byte[] bytes = Convert.FromBase64String(cipherText);
                using (MemoryStream msDecrypt = new MemoryStream(bytes))
                { 
                    aesAlg = new RijndaelManaged();
                    aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
                    aesAlg.IV = ReadByteArray(msDecrypt);
                    ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                            plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
            finally
            {
                if (aesAlg != null)
                    aesAlg.Clear();
            }
            return plaintext;
        }
        private static byte[] ReadByteArray(Stream s)
        {
            byte[] rawLength = new byte[sizeof(int)];
            if (s.Read(rawLength, 0, rawLength.Length) != rawLength.Length)
            {
                throw new SystemException("Stream did not contain properly formatted byte array");
            }
            byte[] buffer = new byte[BitConverter.ToInt32(rawLength, 0)];
            if (s.Read(buffer, 0, buffer.Length) != buffer.Length)
            {
                throw new SystemException("Did not read byte array properly");
            }
            return buffer;
        }
Answer 2

Чтобы дешифратор заработал, необходимо было удалить соль на этапе шифрования (я добавлял ее в конец).

READ ALSO
Не определяется свойство зависимости в wpf?

Не определяется свойство зависимости в wpf?

Разбираюсь со свойствами зависимостиКак я понял, что бы создать свойство зависимости необходимо проделать следующие шаги (сейчас буду их сравнивать...

271
Нанооптимизация в цикле for

Нанооптимизация в цикле for

Например, есть массив с элементами

264
Запрет на создание процессов, работы с файловой системой и интернетом

Запрет на создание процессов, работы с файловой системой и интернетом

Доброго времени суток! При написании подсистемы тестирования пользовательских решений задач по программированию столкнулся с такой проблемой:

172
Как в Angular Material(1.0) использовать один компонент?

Как в Angular Material(1.0) использовать один компонент?

Добрый вечерЕсть вопрос, использую Angular Material для первого Angular'a

205