Что именно делает параметр NoPadding в классе Cipher? - PullRequest
1 голос
/ 27 января 2020
Класс

Java Cipher поддерживает перечисленные там преобразования . Среди них есть несколько NoPadding вариантов:

  • AES / CBC / NoPadding (128)
  • AES / ECB / NoPadding (128)
  • AES / GCM / NoPadding (128)
  • DES / CBC / NoPadding (56)
  • DES / ECB / NoPadding (56)
  • DESede / CBC / NoPadding (168)
  • DESede / ECB / NoPadding (168)

Сначала я предположил, что здесь "заполнение" означает метод, используемый для заполнения последнего блока открытого текста, если размер открытого текста не кратен размеру размер блока шифра.

Но как в таком случае использовать режим блочного шифра, такой как ECB или CB C, без "заполнения"? Предположим, что мы используем AES/ECB/NoPadding для шифрования 250-битного сообщения. Первый блок открытого текста - это, очевидно, первые 128 бит сообщения. Каковы последние 6 бит второго блока открытого текста?

1 Ответ

1 голос
/ 27 января 2020

Ну, во-первых, вы не можете напрямую передать Cipher - в любом режиме - 250-битное сообщение. Причина этого в том, что, как и в большинстве сред выполнения, байт - это наименьший объем данных, который вы можете обработать. Если вы хотите кодировать 250 битов, вам нужно подумать о кодировании этих битов в байтах (например, указав биты в последнем байте, который вы не используете, как это выполняется для кодирования значения ASN, кодированного с помощью DER). определен BIT STRING).


Пример DER BIT STRING только для 11 битов, установленных в 1:

05 FF E0

здесь есть 5 неиспользованных битов в последнем байте (которые установлены в значение 0). Итак, первый байт просто жертвуется, чтобы указать на этот факт - он не является частью значения.


Второй, даже если вход будет кратным 8 битам, тогда вы все равно не сможет шифровать, используя NoPadding для ECB или CB C, режим , если только сам вход уже кратен размеру блока. Если вы укажете NoPadding, тогда, действительно, никакие байты не будут добавлены (даже 00 значащие байты), поэтому вы получите IllegalBlockSizeException , если , размер открытого текста не кратен размеру блока байты для AES и 8 байтов для DES & DES-EDE).

Размер открытого текста - это количество входных байтов, предоставленных методам update и doFinal вместе. Байты для блоков перед последним будут буферизироваться там, где это необходимо - имеет значение только окончательное число.


Из документации Cipher#doFinal:

бросков :

...
IllegalBlockSizeException - если этот шифр является блочным шифром, заполнение не было запрошено (только в режиме шифрования), а общая длина ввода данных, обработанных этот шифр не кратен размеру блока; или если этот алгоритм шифрования не может обработать предоставленные входные данные.
...

Обратите внимание, что это ужасное описание, на мой взгляд: во время расшифровки это исключение будет выдано на doFinal независимо от используемого заполнения (опять же, только для режимов ECB и CB C), если размер не кратен размеру блока. Распаковка происходит только после дешифрования блочным шифром и, в конце концов, режима работы.

Конечно, выход режима ECB и CB C во время шифрования всегда должен быть кратным размеру блока, так что будет означать, что зашифрованный текст был усечен или иным образом изменен перед расшифровкой.


Для заполнения GCM не требуется (шифрование в режиме CTR используется внутри), поэтому NoPadding является единственной реализацией c, и любой объем данных идет - но опять же самый маленький элемент, который должен быть зашифрован Cipher, является байтом. Несмотря на то, что алгоритм GCM указан в битах, а не в байтах, эта реализация не поддерживает его.

...