3

My customer sends to me a JWT, I need to validate this JWT using their public key. I am using Java and JJWT framework to validate this token. I know decode this token using HS256, but using RS256 I don't know.

their configurations is:

enter image description here

Editing here to improve my question. The jjwt example of parse that I am using:

        Claims String secret = "-----BEGIN CERTIFICATE-----myx5ckey-----END CERTIFICATE-----"
    byte[] dataBytes = Base64.getEncoder().encode(secret.getBytes());
    byte[] byteKey = Base64.getDecoder().decode(dataBytes);
    X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(byteKey);
    KeyFactory kf = KeyFactory.getInstance("RSA");

    PublicKey publicKey = kf.generatePublic(X509publicKey);

    Claims body = null;
    body = Jwts.parser().setSigningKey(publicKey.getEncoded())
            .parseClaimsJws(idToken)
            .getBody();


java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format

    at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)

How can I validate the received token using the JWKS informations that I show? (imagem above)

javaTry
  • 1,085
  • 2
  • 18
  • 30

2 Answers2

5

I solved my problem.

String secret2 = "myX5c";
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(secret2)));
        PublicKey publicKey = certificate.getPublicKey();


        Claims body = null;
        body = Jwts.parser().setSigningKey(publicKey)
                .parseClaimsJws(idToken)
                .getBody();

@KcDoD thanks for your tips.

javaTry
  • 1,085
  • 2
  • 18
  • 30
3

tldr; Need to follow three steps

  1. Extract public key from JWK may be going through discovery document or from any other mean.
  2. Extract JWS Signature and JWS Signing input as described by JWS specification
  3. Pass public key, JWS signature and JWS Signing input to signature verifier

Depending on the library, step 2 and 3 may be done in single step.!

Long answer

To validate you have to follow the JWS specification.

JWS specification, defined in RFC7515 explains how to create JWT's MAC needed to validate the token. Appendix 2 of the protocol explains how to create a MAC with RS256 and validate it.

Using the discovery information, you must identify the public key. Now here you have received key details as a JWK. According JWK protocol definition on x5x,

The "x5c" (X.509 certificate chain) parameter contains a chain of one or more PKIX certificates

So basically you have public key in the JWK. Now you need to convert the encoded String of x5x to public key. To do that, please check this already answered question.

Once the public key is constructed use it to validate the token. Following is the extraction from spec.

A.2.2. Validating

Since the "alg" Header Parameter is "RS256", we validate the RSASSA- PKCS1-v1_5 SHA-256 digital signature contained in the JWS Signature.

Validating the JWS Signature is a bit different from the previous example. We pass the public key (n, e), the JWS Signature (which is base64url decoded from the value encoded in the JWS representation), and the JWS Signing Input (which is the initial substring of the JWS Compact Serialization representation up until but not including the second period character) to an RSASSA-PKCS1-v1_5 signature verifier that has been configured to use the SHA-256 hash function.

To validate, its better to use a library. For reference, here is a link to how its done using nimbus

Community
  • 1
  • 1
Kavindu Dodanduwa
  • 12,193
  • 3
  • 33
  • 46