Похоже, ЭТОТ вопрос связан, , но это не так.
В моем случае исключение "заполнение недопустимо и его нельзя удалить" возникает, когда расшифровывает вС этим связан вопрос, когда шифрование
Первый вопрос, который задают люди: что вы пробовали?Я много пробовал.Так что даже после удаления всего лишнего текста мое описание довольно длинное.Извините за это.
Мой вывод состоит в том, что исключение «заполнение недопустимо и не может быть удалено» возникает в 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()
Так что же мне делать, чтобы предотвратить исключение?Читать один фиктивный байт?Кажется немного глупым, не так ли?