Nimbus поддерживает JWS, JWE, JWK и JWT на двух уровнях: низкоуровневые объекты (SignedJWT, ECDSASigner, MACVerifier) и DefaultJWTProcessor, который объединяет выбор ключа, проверку подписи и проверку утверждений. На нём построен сервер ресурсов Spring Security, поэтому его настройки по умолчанию действуют в большинстве API на Spring.
В процессоре списком разрешённых алгоритмов служит JWSVerificationKeySelector: селектор для ES256 отклонил токен RS256 и токен HS256, подписанный текстом PEM ключа EC, с ошибкой Another algorithm expected, or no matching key(s) found, а без селектора процессор отклоняет любые токены. Неподписанные токены отклоняются (Unsecured (plain) JWTs are rejected, extend class to handle). У низкоуровневого API такой защиты нет: MACVerifier, созданный из текста PEM, принял этот поддельный токен HS256, поэтому код, который выбирает объект проверки по заголовку токена, воспроизводит классическую ошибку подмены алгоритма. Используйте процессор, как это делает пример.
DefaultJWTClaimsVerifier по умолчанию допускает расхождение часов в 60 секунд, а exp необязателен, если не указать его среди обязательных утверждений; пример требует sub и exp и фиксирует издателя. ES256 не принимает ключ P-384 (The ES256 algorithm is not allowed or supported by the JWS signer), а подпись в кодировке DER просто не проходит проверку; проверьте длину подписи в отладчике JWT.
В версии 10.10 полный цикл прошли семейства HS, RS, PS и ES, а также EdDSA и более новое имя Ed25519. Для Ed25519 нужна библиотека Google Tink в classpath: без неё подпись завершилась ошибкой NoClassDefFoundError: com/google/crypto/tink/subtle/Ed25519Sign$KeyPair. Для ES256K нужен провайдер с поддержкой secp256k1, например Bouncy Castle, поскольку в JDK такого провайдера нет.
Что публикует поставщик удостоверений, покажет проверка JWKS, а зашифрованные токены разберёт инспектор JWE.