Шифрование большого байтового массива - PullRequest
3 голосов
/ 10 марта 2020

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

Это моя реализация:

val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey())
val encryptedData = cipher.doFinal(textToEncrypt.toByteArray(StandardCharsets.UTF_8))

Как уже говорилось, проблема возникает, только если входной текст слишком большой. Например, если я передам в качестве ввода массив байтов doFinal a длиной 168036, он вернет мне массив байтов длиной 65652.

Связано ли это с ограничением шифра? Если да, есть ли способ увеличить входной буфер?

enter image description here

1 Ответ

3 голосов
/ 10 марта 2020

GVillani82 показывает, что у него есть серьезный Google-Fu; из комментариев:

"Может быть связано с этим https://issuetracker.google.com/issues/123307358?"

Показывает, что это, скорее всего, ошибка во время выполнения 27 и раньше , Предположительно, это исправлено в более поздних версиях, хотя в отчете об ошибке не указано , какая версия.


Однако, возможно, лучше исправить проблему с помощью инкрементных обновлений. В этом случае убедитесь, что ваш буфер строго ниже 64 КБ, скажем, 32 КБ.

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

Другой способ - использовать потоковую передачу. Для шифрования вы обычно используете CipherOutputStream и затем копируете открытый текст в него, либо вручную (снова используя буфер, как вы делаете сейчас), либо просто выполняя метод InputStream.transferTo, если вы хотите записать весь поток. В этом случае вы можете напрямую прочитать байты из ресурса (сохраняя исходную кодировку). Однако в этом случае вы не знаете, какой размер буфера он будет использовать. Если вам нужна потоковая передача, то относительно легко создать свои собственные потоковые классы с помощью вызовов update / doFinal.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...