Получить IV из зашифрованного текста для использования в методе дешифрования - PullRequest
0 голосов
/ 08 октября 2018

Я пытаюсь зашифровать и расшифровать, используя алгоритм AES256, у меня есть следующий код.

 public string Encrypt(string dataToEncrypt, string key)
            {
                if (dataToEncrypt == null || dataToEncrypt.Length <= 0)
                    throw new ArgumentNullException("plainText");
                if (key == null || key.Length <= 0)
                    throw new ArgumentNullException("Key");
                var iv = GenerateRandomNumber(16);
                using (var aes = new AesCryptoServiceProvider())
                {
                    aes.Mode = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;
                    aes.Key = Convert.FromBase64String(key);
                    aes.IV = iv;
                    byte[] data = Encoding.UTF8.GetBytes(dataToEncrypt);
                    using (var memoryStream = new MemoryStream())
                    {
                        var cryptoStream = new CryptoStream(memoryStream, 
                       aes.CreateEncryptor(),
                            CryptoStreamMode.Write);
                        cryptoStream.Write(data, 0, data.Length);
                        cryptoStream.FlushFinalBlock();                    
                        return Convert.ToBase64String(memoryStream.ToArray());
                    }
                }
            }
  public string DecryptReturnsString(string dataToDecrypt, string key)
        {
            if (dataToDecrypt == null || dataToDecrypt.Length <= 0)
                throw new ArgumentNullException("dataToDecrypt");

            if (key == null || key.Length <= 0)
                throw new ArgumentNullException("Key");

            using (var aes = new AesCryptoServiceProvider())
            {
                aes.Mode = CipherMode.CBC;
                aes.Padding = PaddingMode.PKCS7;
                aes.Key = Convert.FromBase64String(key);
                byte[] data= Convert.FromBase64String(dataToDecrypt);
                aes.IV = getIV(data);
                using (var memoryStream = new MemoryStream())
                {
                    var cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(),
                        CryptoStreamMode.Write);

                    cryptoStream.Write(data, 0, data.Length);
                    cryptoStream.FlushFinalBlock();

                    var decryptBytes = Encoding.UTF8.GetString(memoryStream.ToArray());

                    return decryptBytes;
                }
            }
        }

   public byte[] GenerateRandomNumber(int length)
        {
            using (var randomNumberGenerator = new RNGCryptoServiceProvider())
            {
                var randomNumber = new byte[length];
                randomNumberGenerator.GetBytes(randomNumber);

                return randomNumber;
            }
        }
        private static byte[] getIV(byte[] arr)
        {
            byte[] IV = new byte[16];
            Array.Copy(arr, 0, IV, 0, 16);
            return IV;
        }

Здесь я пытаюсь получить IV из зашифрованной строки, но изначально сгенерированный IV и извлеченный IV отличаются, когда я отлаживал, так что это дает мне это исключение: «Заполнение недопустимо ине может быть удален. "

Может кто-нибудь, пожалуйста, посмотрите на мой метод GetIV () и дайте мне знать, где я делаю неправильно.

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Есть две проблемы.

  1. Кажется, вы не отправляете IV по своему зашифрованному тексту (это не сделано само по себе).Обычная практика - добавление IV к зашифрованному тексту.Так, как прокомментировал Роберт, вы можете записать IV в поток памяти непосредственно перед шифрованием

  2. при расшифровке, вы можете прочитать IV (первые байты ваших данных , но расшифроватьтолько остальные (подмассив 16 .. длина)

0 голосов
/ 09 октября 2018

IV в режиме работы CBC необходимо отправлять в виде открытого текста, иначе вы не сможете расшифровать.В этом нет проблемы безопасности.

, как сказал Роберт, добавьте его к началу потока.

см.

var mergedStream = new MergedStream(new Stream 
{
    new MemoryStream(iv),
    cryptoStream,
}
...