Итоговый размер aes

236
18 августа 2017, 23:23

Необходимо узнать размер выходных данных зашифрованных с помощью aes.

В интернете нашел формулу

int endSize = (startSize / 16) * 16 + (startSize%16 == 0 ? 0 : 16)

Логика понятна - если размер не влезает кратно в блоки aes (которые 16 байт), то выравниваем до кратного. Однако оказалось, что более правильная формула

int endSize = (startSize / 16) * 16 + 16

Тестовый пример:

var pdb = new Rfc2898DeriveBytes("12345", iv);
var aes = new AesManaged();
aes.Key = pdb.GetBytes(aes.KeySize / 8);
aes.IV = pdb.GetBytes(aes.BlockSize / 8);
var buffer = new byte[4096];
using (var instream=File.OpenRead("z:/in.txt"))
{
      using (var crptoStream=new CryptoStream(instream,
           aes.CreateEncryptor(), CryptoStreamMode.Read))
      {
           using (var outstream = File.OpenWrite("z:/out.bin"))
           {
               do
               {
                    var count = crptoStream.Read(buffer, 0, buffer.Length);
                    if(count==0)break;
                    outstream.Write(buffer, 0, count);
                } while (true);
            }
      }
}

Для проверки взял файл 15 байт - на выходе ожидаемые 16 байт. Добавил байт. 16 байт на входе - на выходе 32.

Почему так получается? Данных хватает и Padding по идее не должен вмешиваться.

Answer 1

Выравнивание по PKCS#7 описано в RFC5652.

For such algorithms, the method shall be to pad the input at the trailing end with k - (l mod k) octets all having value k - (l mod k), where l is the length of the input.

Формула k - (l mod k) (где l - длина входных данных, k - размер блока) в случае входных данных кратных 16 будет равен 16, то есть еще 16 байт будут записаны в виде открытого текста равного 16. Таким образом, выравнивания будут выглядеть так:

                 01 -- if lth mod k = k-1
              02 02 -- if lth mod k = k-2
                  .
                  .
                  .
        k k ... k k -- if lth mod k = 0

Важно: Этот метод заполнения хорош тогда и только тогда, когда k меньше 256.

А формула для вычисления конечного размера:

int endSize = startSize + (k - (startSize % k)); //, где k - размер блока
Answer 2

Потому что ты используешь стандартный Padding - PKCS7. Как минимум 1 байт используется для хранения количества добавленных байт.

READ ALSO
Как правильно работает Thread.Sleep(0)?

Как правильно работает Thread.Sleep(0)?

Правильно ли я понимаю, только когда в while придет false, тогда закончится метод StartWork?

186
Редактирование XML-datagrid в WPF и паттерн MVVM

Редактирование XML-datagrid в WPF и паттерн MVVM

Добрый день, извините сразу, перелазил 720 страниц различной инфы не нашел, суть вопроса как работать с XML файлами, редактирование, добавление...

380
Создание файлов COMTRADE в C# при помощи GSF.Comtrade

Создание файлов COMTRADE в C# при помощи GSF.Comtrade

Понимаю, что очень узконаправленный вопрос, однако офдокументация скупа на ответы

261
Конструктор классов

Конструктор классов

Например есть такой класс(к примеру)

194