. NET Базовый шифр AES CryptoStream всегда 16 байтов - PullRequest
0 голосов
/ 16 января 2020

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

var provider = Aes.Create();
provider.Mode = CipherMode.CBC;
provider.Padding = PaddingMode.PKCS7;
using var encryptor = provider.CreateEncryptor();
using var memoryStream = new MemoryStream();
using var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
using var streamWriter = new StreamWriter(cryptoStream, Encoding.UTF8);
streamWriter.Write(plainText);
cryptoStream.FlushFinalBlock();
var cipher = memoryStream.ToArray();

Это успешно создает байтовый массив, хотя независимо от длины открытого текста, шифр всегда составляет 16 байтов. Насколько я понимаю, с размером блока 16, текстовая строка длиной 16 или более должна приводить к шифру, который больше 16 байтов. Кроме того, даже для открытого текста размером менее 16 байт расшифровка всегда приводит к пустой строке.

var provider = Aes.Create();
provider.Mode = CipherMode.CBC;
provider.Padding = PaddingMode.PKCS7;
using var decryptor = _provider.CreateDecryptor(key, iv);
using var memoryStream = new MemoryStream(cipher);
using var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
using var streamReader = new StreamReader(cryptoStream, Encoding.UTF8);
var plainText = streamReader.ReadToEnd();

Мой код основан на этом образце в документах Microsoft, хотя я ' После вызова в поток я вызываю cryptoStream.FlushFinalBlock(), хотя это не работает должным образом.

1 Ответ

0 голосов
/ 17 января 2020

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

Однако, используя потоковый API generi c, предпочтительно с оператором using и закрытие потока, следует записать любые байты, оставленные в буфере + любое заполнение, которое может потребоваться.

Конечно, вы должны включить в этот оператор using любой поток, записывающий в CryptoStream, иначе они могут иметь оставшиеся данные. Конечно, приемный поток должен быть закрыт только после того, как данные были получены, например, в случае использования MemoryStream.

...