2010-08-13 5 views
3

Я делаю расшифровку AES CBC в java с помощью javax.crypto. Я использую следующие методы Cipher класса:Cipher.doFinal размер выходного файла

  • public final void init (int opmode, Key key, AlgorithmParameters params) метод инициализации,
  • final int update(byte[] input, int inputOffset, int inputLen, byte[] output) метод для дешифрования данных,
  • и, наконец, я называю метод final int doFinal(byte[] output, int outputOffset) закончить расшифровку.

Мой запрос таков: могу ли я предположить, что размер данных, возвращаемых мне вызовом doFinal, всегда будет меньше или равен размеру блока AES? Документация описывает метод doFinal как:

«Завершает преобразование с несколькими частями (шифрование или дешифрование). Процессы любые байты, которые могут быть буферизированы в предыдущих вызовах обновления. Окончательные преобразованные байты хранятся в выходном буфере.»

Но нигде не говорится о том, что выходной буфер будет содержать не более одного блока данных. Хотя я понимаю, что это общее поведение API AES, и это поведение, которое мой код проявил до сих пор, но будет ли это предположение всегда выполняться?

+0

Чтобы быть ясным, мне нужно вызвать функцию обновления несколько раз, когда я получаю зашифрованные данные в кусках. У меня нет всех зашифрованных данных, поэтому я не могу сделать один вызов doFinal, чтобы получить результат за один шаг. – vikas

ответ

3

общий (как в, в контексте класса Cipher) Я не верю, что было бы безопасно предположить это. Согласно javadocs для этого doFinal метода:

Если выходной буфер слишком мал, чтобы удержать результат, однако ShortBufferException отбрасывается. В этом случае повторите этот вызов с большим выходным буфером. Используйте getOutputSize, чтобы определить, насколько большой должен быть выходной буфер.

Таким образом, если вы распределение выходного буфера «вблизи» точка, где вы вызываете метод doFinal, то сделать бы смысл называть getOutputSize и выделяет буфер соответствующего размера. Работа выполнена.

С другой стороны, если вы проходите в буфере из «далекого», который был создан точно в размере блока, у вас может быть больше проблем. Было бы совершенно законно (по крайней мере, в соответствии с публичным интерфейсом класса Java) для реализации Cipher для возврата вывода, большего чем размер блока, если метод getOutputSize возвращает соответствующий размер.

На самом деле, если вы используете дешифрование CBC, не требуется ли передавать в все из блоков в метод update? В этом случае вы должны получить полный вывод открытого текста с doFinal, а не только на один блок?

+0

Можно ли использовать байтовый массив 'getOutputSize (фиксированный размер ввода)' для 'update' и 'doFinal'? –

+0

@Jin Я не знаю, будет ли это иметь какой-то реальный смысл, поскольку это две разные вещи. Байт-массив, предоставленный для 'update', должен быть размером данных, которые вы обновляете шифром, - он должен быть того же размера, что и количество байтов в * input *. Если это определенно меньше или равно 'getOutputSize()', то вы * можете * повторно использовать один и тот же массив. На практике, хотя я подозреваю, что это будет более запутанным, чем полезным. –

0

Вообще говоря, небезопасно предполагать, что буферизация предназначена только для одного блока; и когда вы смотрите на детали, вы можете видеть, что это зависит от типа заполнения. С обычным дополнением «PKCS # 5» добавляется не менее одного байта и не более n байтов (для блоков размера n), поэтому система дешифрования может ограничиться n байтов буферизации. Некоторые другие типы дополнений являются немного более сложными, например.CTS2n байт буферизации. Криптографический уровень Java, похоже, сейчас не поддерживает CTS, но это может быть добавлено в будущую версию.

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

Можно с уверенностью предположить, что общая длина дешифрованного сообщения больше, чем общая длина зашифрованного сообщения (симметричное шифрование не включает сжатие данных). Таким образом, вы можете поддерживать два счетчика: один для байтов входных данных (зашифрованные блоки) и один для байтов полученных выходных данных; разница будет максимальной границей для того, что можно получить от doFinal(). Но вот что делает getOutputSize().

+0

Прокладка, используемая в моем случае, это только «PKCS5Padding». Означает ли это, что я могу предположить, что максимальный размер вывода будет AES Block Size? Причина, по которой я не могу использовать «Cipher.getOutputSize (len)», заключается в том, что буфер для хранения вывода «doFinal()» выделяется и передается моему модулю из кода, издаваемого далеко далеко, и я не должен изменять его. Размер этого выделенного буфера - это размер блока AES. – vikas

+0

Вы не можете этого догадаться, но можете проверить это. Если блоки имеют размер _n_, а зашифрованное сообщение состоит из блоков _k_, то общая длина расшифрованного сообщения находится между _n (k-1) _ и _ (nk) -1_ (включительно). С помощью счетчиков вы можете знать (во время выполнения), будут ли оставшиеся буферизованные данные вписываться в буфер размером _n_ при расшифровке. Вы не можете предположить, что _in advance_, потому что это не гарантированное свойство криптографической архитектуры Java. –

 Смежные вопросы

  • Нет связанных вопросов^_^