JWT расшифровывает, но выдает ошибку проверки Mac
У меня есть приложение весенней загрузки jhipster, которое принимает токен, сгенерированный третьей стороной, который был зашифрован нашим открытым ключом. У меня есть JWTFilter, который расшифровывает токен с помощью нашего закрытого ключа и создает объект аутентификации, который хранится в контексте безопасности. Как только выполнение достигнет контроллера, я намереваюсь извлечь имя пользователя и пароль из контекста безопасности, чтобы я мог сделать вызовы API обратно стороннему приложению.
В некоторой степени это работает в нашей среде интеграции, где сторонняя сторона имеет ссылку на работающий экземпляр нашего приложения. Чтобы проверить локально, я нажимаю на ссылку в среде интеграции и копирую токен. Затем я делаю запрос от Postman к экземпляру нашего приложения, которое я запускаю локально, с токеном, добавленным в заголовки, так же, как и наш js-клиент.
Я использую "com.nimbusds:nimbus-jose-jwt:4.23" для расшифровки, и я получаю ошибку "Проверка MAC не удалась". Я могу изменить значение macCheckPassed на true в отладчике, и расшифровка будет завершена, что позволит мне увидеть утверждения и загрузить их в контекст безопасности. Однако какой-то другой фильтр ловит мой взлом, и запрос отклоняется с ошибкой авторизации.
public static byte[] decryptAuthenticated(final SecretKey secretKey,
final byte[] iv,
final byte[] cipherText,
final byte[] aad,
final byte[] authTag,
final Provider ceProvider,
final Provider macProvider)
throws JOSEException {
// Extract MAC + AES/CBC keys from input secret key
CompositeKey compositeKey = new CompositeKey(secretKey);
// AAD length to 8 byte array
byte[] al = AAD.computeLength(aad);
// Check MAC
int hmacInputLength = aad.length + iv.length + cipherText.length + al.length;
byte[] hmacInput = ByteBuffer.allocate(hmacInputLength).
put(aad).
put(iv).
put(cipherText).
put(al).
array();
byte[] hmac = HMAC.compute(compositeKey.getMACKey(), hmacInput, macProvider);
byte[] expectedAuthTag = Arrays.copyOf(hmac, compositeKey.getTruncatedMACByteLength());
boolean macCheckPassed = true;
if (! ConstantTimeUtils.areEqual(expectedAuthTag, authTag)) {
// Thwart timing attacks by delaying exception until after decryption
macCheckPassed = false;
}
byte[] plainText = decrypt(compositeKey.getAESKey(), iv, cipherText, ceProvider);
if (! macCheckPassed) {
throw new JOSEException("MAC check failed");
}
return plainText;
}
Что это за проверка MAC? Я думал, что это связано с происхождением токена. Что-то вроде того, что токен был зашифрован с помощью MAC-идентификатора исходной системы, что выдает ошибку, когда он не синхронизируется с моим текущим хостом.
Какой другой фильтр отклонил бы запрос, если расшифровка прошла? Есть ли какой-то другой флаг, который я должен установить, чтобы фреймворк удовлетворил запрос?
1 ответ
Спецификация JWE требует аутентифицированного шифрования, чтобы гарантировать, что простой текст не только зашифрован, но и защищен от взлома. Чтобы убедиться, что HMAC применяется после шифрования содержимого.
Ошибка "Проверка Mac не удалась" может означать две вещи: библиотека, которая создала исходный JWE / JWT, неправильно применила HMAC, или JWE / JWT была изменена при передаче.