JWT токен, сгенерированный на сервере, не проходит валидацию в микросервисе с использованием того же ключа

Решаю задачу на работе. Нужно сделать аутентификацию пользователей по jwt токену. Имеется сервер, где генерируются токены, и микросервис, где по токену надо авторизоваться.

На сервере используется такая библиотека jwt:

<!-- JWT -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

В микросервисе используется такой набор библиотек:

<dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.12.6</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.12.6</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.12.6</version>
            <scope>compile</scope>
        </dependency>

На сервере токен генерируется таким образом:

token = Jwts.builder()
                    .setId(id)
                    .setHeaderParams(Head)
                    .setIssuedAt(now)
                    .setNotBefore(now)
                    .setExpiration(exp)
                    .signWith(SignatureAlgorithm.HS256, (ServerSetting.SettingRestNow.getSecretWord()))
                    .compact();

Здесь значение ServerSetting.SettingRestNow.getSecretWord() равно +z0yMXCguMRkUn0tBU/TS9Losbss13Ougqz+jRtEbRqzF4eEfadpJ+dySOo6rswu. Библиотека старая и в ней внутри метода signWith передаваемое значение декодируется как строка base64.

Работу с токенами в микросервисе я приведу в модельном виде, но там происходит примерно то же самое.

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

public class Main {

    public static void main(String[] args) {
        String test = "eyJEb2wiOiLQmtC-0LzQvNC10YDRh9C10YHQutC40Lkg0LTQuNGA0LXQutGC0L7RgCIsIkxvZyI6IldlbGNvbWVSIiwiUG9zIjowLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJiY2VmOTA1M2FiMjQ0ODQxYTk3NjQzNzIzNjNjZWU2ZiIsImlhdCI6MTcyNTkwNjE0OCwibmJmIjoxNzI1OTA2MTQ4LCJleHAiOjIwODU5NjUyODd9.yh-sKO-zXROrQPt-U-XXAhso5mMnDwuEoJ6Ff0KGrY0";

        String token = Jwts.builder().subject("test")
                .issuedAt(new Date(System.currentTimeMillis()))
                .expiration(new Date(System.currentTimeMillis() + 100000 * 60 * 24))
                .signWith(getSigninKey())
                .compact();

        System.out.println(token);

        Claims decoded = Jwts.parser().setSigningKey(getSigninKey())
                .build()
                .parseClaimsJws(token)
                .getBody();

        System.out.println(decoded);

        Claims claims = Jwts.parser().verifyWith(getSigninKey())
                .build()
                .parseClaimsJws(test)
                .getBody();

        System.out.println(claims);
    }

    private static SecretKey getSigninKey() {
        String key = "+z0yMXCguMRkUn0tBU/TS9Losbss13Ougqz+jRtEbRqzF4eEfadpJ+dySOo6rswu";
        byte[] keyBytes = Decoders.BASE64.decode(key);

        return new SecretKeySpec(keyBytes, "HmacSHA256");
    }

Здесь test - токен, полученный с сервера. Надо его распарсить в "микросервисе". Строка +z0yMXCguMRkUn0tBU/TS9Losbss13Ougqz+jRtEbRqzF4eEfadpJ+dySOo6rswu здесь декодируется как base64 потому, что то же самое происходит в местоде signWith на сервере, см. выше.

Проблема в том, что при парсинге токена с сервера с использованием того же ключа, который используется на сервере, происходит ошибка: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted. То есть не происходит валидация сигнатуры, ключ некорректный. Как так могло получиться, что ключ не подходит, если в микросервисе я использую тот же самый ключ, что и на сервере? Разница в том, что на сервере внутри библиотеки ключ декодируется, а в микросервисе я декодирую его сам (получается символьный шум, но это не суть важно).

Систему писали люди, не разбирающиеся в криптографии, а мне надо быстро это поправить. В чем тут может быть проблема?

На сайте jwt.io этот токен валидируется и декодируется корректно с ипользованием ключа +z0yMXCguMRkUn0tBU/TS9Losbss13Ougqz+jRtEbRqzF4eEfadpJ+dySOo6rswu в приведенном виде без дополнительного кодирования.


Ответы (0 шт):