Размер данных после шифрования AES / CBC и AES / ECB - PullRequest
56 голосов
/ 19 июля 2010

Я хотел бы знать размер данных после шифрования AES, чтобы избежать буферизации моих данных после AES (на диске или в памяти), главным образом, для определения размера.

Я использую 128-битный AES и javax.crypto.Cipher и javax.crypto.CipherInputStream для шифрования.

Несколько тестов, выполненных с различными размерами входных данных, показывают, что размер последующего шифрования, рассчитанный, как показано ниже, является правильным:

long size = input_Size_In_Bytes; 
long post_AES_Size = size + (16 - (size % 16));

Но я не уверен, применима ли приведенная выше формула для всех возможных входных размеров.

Есть ли способ рассчитать размер данных после применения шифрования AES - заранее без необходимости буферизовать зашифрованные данные (на диске или в памяти), чтобы узнать их размер после шифрования?

Ответы [ 8 ]

76 голосов
/ 19 июля 2010

AES имеет фиксированный размер блока 16 байтов независимо от размера ключа.Предполагая, что вы используете заполнение PKCS 5/7, используйте эту формулу,

 cipherLen = (clearLen/16 + 1) * 16;

Обратите внимание, что если открытый текст кратен размеру блока, для заполнения необходим целый новый блок.Скажем, у вас открытый текст 16 байтов.Текст шифра будет занимать 32 байта.

Возможно, вы захотите сохранить IV (исходный вектор) вместе с текстом шифра.В этом случае вам нужно добавить еще 16 байтов для IV.

30 голосов
/ 19 июля 2010

AES, как блочный шифр, не меняет размер. Размер ввода всегда равен размеру вывода.

Но AES, являясь блочным шифром, требует, чтобы ввод был кратным размеру блока (16 байт). Для этого используются схемы заполнения , подобные популярным PKCS5 . Поэтому ответ таков: размер ваших зашифрованных данных зависит от используемой схемы заполнения. Но в то же время все известные схемы заполнения округляются до следующего размера модуля 16 (размер AES имеет размер блока 16 байт).

8 голосов
/ 19 июля 2010

Это зависит от режима, в котором вы используете AES. То, что у вас есть, является точным для большинства блочно-ориентированных режимов, таких как ECB и CBC. OTOH, в режиме CFB (для одного примера) вы в основном просто используете AES для создания потока байтов, который вы XOR с байтами ввода. В этом случае размер вывода может оставаться размером ввода, а не округляться до следующего размера блока, как вы указали выше.

5 голосов
/ 16 июня 2016

Вообще говоря, для шифрования блочным шифром:

CipherText = PlainText + Block - (Блок Block PlainText MOD)

Размер зашифрованного текста вычисляется как размер открытого текста, расширенного доследующий блок.Если используется заполнение, а размер открытого текста является точным кратным размеру блока, будет добавлен один дополнительный блок, содержащий информацию о заполнении.

AES использует размер блока 16 байтов, что дает:

CipherText = PlainText + 16 - (PlainText MOD 16)

Источник: http://www.obviex.com/articles/CiphertextSize.pdf

Примечание:

  1. CipherText и PlainText представляют размерсоответственно зашифрованного текста и размера обычного текста.
3 голосов
/ 19 июля 2010

Шифр ​​AES всегда работает с 16-байтовыми (128-битными) блоками. Если количество входных байтов не является точным кратным 16, оно дополняется. Вот почему 16 кажется «магическим числом» в ваших расчетах. То, что у вас есть, должно работать для всех входных размеров.

1 голос
/ 19 июля 2010

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

0 голосов
/ 21 февраля 2018

Если ваша входная длина меньше максимального размера int, вы можете использовать Cipher.getOutputSize (int)

0 голосов
/ 20 июля 2010

Существуют подходы к хранению зашифрованной информации, которые исключают необходимость какого-либо дополнения при условии, что размер данных по крайней мере равен размеру блока.Одна небольшая трудность состоит в том, что, если размер данных может быть меньше размера блока, и если должна быть возможность восстановить точный размер данных, даже для небольших блоков, вывод должен быть как минимум на один бит больше, чемinput, [i] независимо [/ i] от размера данных.

Чтобы понять проблему, следует понимать, что существует 256 ^ N возможных файлов длиной N байтов и число возможных файлов, которые не имеютдлина, превышающая N байтов, равна 256 ^ N плюс количество возможных файлов длиной не более N-1 байта (существует один возможный файл длиной 0 байт и 257 возможных файлов длиной не более одного байта).

Если размер блока составляет 16 байтов, то будут 256 ^ 16 + 256 ^ 14 + 256 ^ 13 и т. Д. Возможные входные файлы длиной не более 16 байт, но только 256 ^ 16 возможных выходных файловдлиной не более 16 байт (поскольку выходные файлы не могут быть короче 16 байт).Поэтому, по крайней мере, некоторые возможные 16-байтовые входные файлы должны расти.Предположим, они станут 17 байтами.Есть 256 ^ 17 возможных семнадцати байтовых выходных файлов;если какой-либо из них используется для обработки входных данных размером 16 байт или меньше, не будет достаточно доступных для обработки всех возможных 17-байтовых входных файлов.Независимо от того, насколько большим может быть ввод, некоторые файлы этого размера или больше должны расти.

...