javax.crypto.AEADBadTagException — AES / GCM / NoPadding работает, затем нет

#java #exception #cryptography #aes

#java #исключение #криптография #aes

Вопрос:

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

При поиске ошибки я взял инициализацию шифрования и ввел цикл вокруг расшифровки. Т.е.

 GCMParameterSpec parameterSpec = new GCMParameterSpec(authenticationTagLength, ivByte);
cipher = Cipher.getInstance(AES_MODE_GCM);
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameterSpec);
if (additionalDataText.length()>0) {
    cipher.updateAAD(additionalDataText.getBytes("UTF-8"));
    }                        }
for(int i = 0; i < 500; i  ) {
    cipher.doFinal(cypherBytes);
}
  

Запустив этот код несколько раз, я получаю 17/500 успехов с первой попытки, затем ноль для следующих нескольких попыток. Изменение кода и разрешение Eclipse перестроить может привести к 17 или 18 успехам, за которыми следуют сбои.

Исключение заключается в следующем

 [err] javax.crypto.AEADBadTagException
[err]   at com.ibm.crypto.provider.GCTRInHardware.gcm_ad(Unknown Source)
[err]   at com.ibm.crypto.provider.aA.c(Unknown Source)
[err]   at com.ibm.crypto.provider.AESGCMCipher.engineDoFinal(Unknown Source)
[err]   at com.ibm.crypto.provider.AESGCMCipher.engineDoFinal(Unknown Source)
[err]   at javax.crypto.Cipher.doFinal(Unknown Source)
  

О да, я использую Java 1.8 на «IBM J9 VM», если это поможет.

Есть ли у кого-нибудь идеи, что может вызвать такое поведение? С наилучшими пожеланиями

Редактировать: в дополнительных новостях это, похоже, вызвано чем-то на сервере, на котором это запущено — я могу успешно расшифровать те же данные на другом сервере и в тестировании JUnit. Я посмотрю, смогу ли я найти разницу в конфигурациях.

Решение В моей jvm.options я указал профилировщик YourKit в параметре -agentpath, удалив эту строку из параметров, я заставил ее работать.

Комментарии:

1. Вы должны выполнить updateAAD в цикле for. Завершите сброс шифрования в состояние после вызова метода init.

2. .getBytes("UTF-8") является подозрительным. Никогда не используйте String при работе с двоичными данными. Просто используйте массив байтов.

3. @rustyx как вы хотите поступить, если вам нужно зашифровать текст?

4. Извините, я не видел, что это было в режиме дешифрования. Я согласен с вами!

5. Прежде всего, спасибо за предложения. Я переместил updateAAD в цикл, но безрезультатно. Я также переключил дополнительные байты в byte[] и передал их в кодировке Base64. Это также не помогло. Что еще более досадно, я переместил код-нарушитель в JUnit-тест, и там он выполняется успешно. Итак, я предполагаю, что что-то в моей среде сломано, но я не знаю, что.

Ответ №1:

Хорошо, я не знал, что это будет актуально: я использую сервер профилей Websphere Liberty. Как упоминалось в моей правке, код работает в JUnit и на другом сервере. Я проверил различия и заставил его работать, поэтому я переделал различия одно за другим и обнаружил, что это было следующее:

В моей jvm.options я указал профилировщик YourKit в параметре -agentpath, удалив эту строку из параметров, я заставил ее работать.

Не уверен, каков этикет при ответе на ваши собственные вопросы, поэтому я также добавлю это к вопросу.