Почему проверка не выполняется для подписи JWS?

#java #jwt #open-banking

#java #jwt #открытый банкинг

Вопрос:

Я пытаюсь подписать сообщение с помощью отдельной полезной нагрузки, используя библиотеку Nimbus JOSE JWT на Java. Проверка проходит локально, но всякий раз, когда я пытаюсь отправить ее на сервер с помощью Postman, я получаю: "The signature header x-jws-signature was parsed and has a valid JOSE header that complies with the specification. However, the signature itself could not be verified"

  JWSSigner signer = new RSASSASigner(privateKey);

        HashMap<String, Object> criticalParameters = new HashMap<>();
        criticalParameters.put("http://openbanking.org.uk/iat", 1501497671);
        criticalParameters.put("http://openbanking.org.uk/iss", orgId);
        criticalParameters.put("http://openbanking.org.uk/tan", "openbankingtest.org.uk");

        JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.PS256)
                .type(JOSEObjectType.JOSE)
                .keyID(keyID)
                .criticalParams(criticalParameters.keySet())
                .customParams(criticalParameters)
                .build();

        // With encoding the payload
        JWSObject jwsObject = new JWSObject(header, payload);
        jwsObject.sign(signer);

        String jws = jwsObject.serialize(true);


        JWSObject parsedJWSObject = JWSObject.parse(jws, payload);

        if (parsedJWSObject.verify(new RSASSAVerifier(publicKey, criticalParameters.keySet()))) {
            System.out.println(parsedJWSObject.serialize(true));
        } else {
            System.out.println("Invalid");
        }
        //=============================

        // Without encoding the payload
        Base64URL signature = signer.sign(header, (header.toBase64URL().toString()   "."   payload).getBytes());
        JWSVerifier verifier = new RSASSAVerifier(publicKey, criticalParameters.keySet());

        boolean isValid = verifier.verify(header, (header.toBase64URL().toString()   "."   payload).getBytes(), signature);
        System.out.println(header.toBase64URL().toString()   ".."   signature.toString());
        System.out.println(isValid);
        //=============================
 

Обе функции успешно подписывают и проверяют JWS, но по какой-то причине это не работает. Если это поможет, я попытаюсь получить доступ к Open Banking API.

Ответ №1:

Совсем недавно возникла аналогичная проблема. Я бы посоветовал вам проверить следующее:

  • Является ли полезная нагрузка в запросе точно такой же, как та, которая используется для подписи JW (без экранирования или форматирования символов)?
  • Каков порядок свойств JSON в полезной нагрузке и предъявляет ли финансовая организация, с которой вы пытаетесь взаимодействовать, особые требования к порядку этих полей JSON?

Я знаю, что очень сомнительно ожидать, что свойства json в полезной нагрузке будут в определенном порядке, но по опыту я узнал, что некоторые реализации open banking предполагают определенный порядок (даже не алфавитный), и они завершатся ошибкой с этой ошибкой, когда порядок не тот, который они ожидают.