Когда DECRYPTING: заполнение недопустимо и не может быть удалено, если ничего не прочитано - PullRequest
0 голосов
/ 07 июня 2018

Похоже, ЭТОТ вопрос связан, , но это не так.
В моем случае исключение "заполнение недопустимо и его нельзя удалить" возникает, когда расшифровывает вС этим связан вопрос, когда шифрование

Первый вопрос, который задают люди: что вы пробовали?Я много пробовал.Так что даже после удаления всего лишнего текста мое описание довольно длинное.Извините за это.

Мой вывод состоит в том, что исключение «заполнение недопустимо и не может быть удалено» возникает в CryptoSteam.FlushFinalBlock, который вызывается CryptoStream.Dispose().Это происходит, если ничего не было прочитано из потока.

Ссылочный источник CryptoStream.FlushFinalBlock

Если я прочитал все данные или хотя бы один байт во время расшифровкипроцесс все работает нормально.

Если я ничего не читаю, я получаю CryptoGraphicException. Заполнение недопустимо и не может быть удалено.

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

  • Ниже полного цикла шифрования / дешифрования.Работает нормально, без исключений, нет необходимости менять отступы по умолчанию, FlushFinalBlock не требуется.Считанные данные равны исходным данным
  • Если я читаю только один байт: исключений тоже нет, нет необходимости изменять заполнение по умолчанию, не требуется FlushFinalBlock.Правильный Dispose () позаботится об этом
  • Если я ничего не читаю, я получаю упомянутое исключение
  • Дополнительный FlushFinalBlock перед Dispose не помогает

Приведенный ниже код демонстрирует полную корректно работающую процедуру тестирования шифрования / дешифрования.Дешифрованные байты равны исходным байтам:

Данные:

byte[] key;
byte[] iv;
byte[] testData = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
byte[] encryptedData;
byte[] decryptedData;

Шифрование данных:

using (Stream testStream = new MemoryStream(testData))
{
    using (RijndaelManaged rijndael = new RijndaelManaged())
    {   // Generate and remember keys:
        rijndael.GenerateKey();
        rijndael.GenerateIV();
        key = rijndael.Key;
        iv = rijndael.IV;

        using (var encryptor = rijndael.CreateEncryptor())
        {
            using (var cryptoStream = new CryptoStream(testStream, encryptor,
                   CryptoStreamMode.Read))
            {   // read all bytes from the cryptoStream and put in a EncryptedData
                using (BinaryReader reader = new BinaryReader(cryptoStream))
                {
                    encryptedData = reader.ReadBytes(10000);
                    // expect no bytes anymore
                }
            }
        }
    }
}

Все TestBytes зашифрованы в encryptedData.ключ и iv известны

дешифрование данных

using (Stream encryptedStream = new MemoryStream(encryptedData))
{
    using (var rijnDael = new RijndaelManaged())
    {
        rijnDael.Key = key;
        rijnDael.IV = iv;
        using (var decryptor = rijnDael.CreateDecryptor())
        {
            using (Stream decryptedStream = new CryptoStream(encryptedStream, decryptor,
                   CryptoStreamMode.Read))
            {
                using (BinaryReader reader = new BinaryReader(decryptedStream))
                {
                    decryptedData = reader.ReadBytes(1000);
                    // expect no bytes anymore
                }
            }
        }
    }
}

// Check that the decrypted data equals the original data:
Debug.Assert(testData.SequenceEqual(decryptedData));

Это прекрасно работает.Если я читаю только один расшифрованный байт, исключений нет:

using (BinaryReader reader = new BinaryReader(decryptedStream))
{
    byte b = reader.ReadByte();
}

Однако, если я ничего не читаю, возникает исключение:

using (Stream decryptedStream = new CryptoStream(encryptedStream, decryptor,
       CryptoStreamMode.Read))
{
    using (BinaryReader reader = new BinaryReader(decryptedStream))
    {
    } // exception during Dispose()
}

Один из ответов в упомянутом связанном вопросев начале включен FlushFinalBlock.Это не помогает, как и ожидалось, потому что CrypteStream.Dispose уже вызывает это

using (Stream decryptedStream = new CryptoStream(encryptedStream, decryptor,
       CryptoStreamMode.Read))
{
    using (BinaryReader reader = new BinaryReader(decryptedStream))
    {
        if (!decryptedStream.HasFlushedFinalBlock)
        { 
            decryptedStream.FlushFinalBlock();
            // even though it hasn't flushed the final bloc
            // I get the same Exception during Flush
         }
    } 
}

Так что теперь мы знаем, что исключение происходит из-за CryptoStream.FlushFinalBlock, что также происходит в CryptoStream.Dispose()

Проблема не имеет ничего общего с бинарным ридером.Если я читаю непосредственно один байт, то исключений нет, и, не читая ничего, я получаю исключение во время удаления CryptoStream

using (Stream decryptedStream = new CryptoStream(encryptedStream, decryptor,
       CryptoStreamMode.Read))
{
    int b = decryptedStream.ReadByte();
} // exception during Dispose()

Так что же мне делать, чтобы предотвратить исключение?Читать один фиктивный байт?Кажется немного глупым, не так ли?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...