JWT расшифровывает, но выдает ошибку проверки Mac

У меня есть загрузочное приложение jhipster spring, которое принимает токен, сгенерированный третьей стороной, который был зашифрован нашим открытым ключом. У меня есть 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 исходной системы, что выдает ошибку, когда он не синхронизируется с моим текущим хостом.

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


person thejames42    schedule 25.04.2017    source источник


Ответы (1)


Спецификация JWE предписывает шифрование с проверкой подлинности, чтобы гарантировать, что обычный текст не просто зашифрован, но и защищены от несанкционированного доступа. Чтобы обеспечить применение HMAC после шифрования контента.

Ошибка «Проверка Mac не удалась» может означать две вещи: библиотека, создавшая исходный JWE/JWT, неправильно применила HMAC или JWE/JWT был изменен при передаче.

person Vladimir Dzhuvinov    schedule 26.04.2017