简体   繁体   中英

Verifying JWT Signature using public key endpoint

I'm wanting to verify the signature of some JWTs from Microsoft. I'm using Spring-Boot, the JJWT library and following endpoint: https://login.microsoftonline.com/common/discovery/v2.0/keys

The endpoint returns an array of JSON public keys. Here is one example from the array.

 {
            "kty": "RSA",
            "use": "sig",
            "kid": "9FXDpbfMFT2SvQuXh846YTwEIBw",
            "x5t": "9FXDpbfMFT2SvQuXh846YTwEIBw",
            "n": "kvt1VmR4nwkNM8jMU0wmj2gSS8NznbOt2pZI6Z7HQT_esF7W19GZR7Y72Xo1i5zXRDM9o3GeTIjBrnr3yy41Q_EaUQ7C-b-Hmg94Vy7EBZyBhi_mznz0dYWs2MIXwR86Nni9TmgTXvjgTPF2YGJoZt4TwcMFefW8rijCVyNrCBA0XspDouNJavvG0BEMXYigoThFjLRXS5U3h4BDfNZFZZS3dyliNOXfgRn2k7oITz8h_ueiPvmDRFh38AeQgx1cELhKWc3P5ugtttraSwgH7nP2NUguO9nCrHuL6TZ-KWpmRWZqwH-jYKFQVt3CDpzwNM6XJL-oHbl1x-gI3YYX5w",
            "e": "AQAB",
            "x5c": [
                "MIIDBTCCAe2gAwIBAgIQZSAeaqWig4BHC1ksmNNcgjANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTE3MDUwNjAwMDAwMFoXDTE5MDUwNzAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJL7dVZkeJ8JDTPIzFNMJo9oEkvDc52zrdqWSOmex0E/3rBe1tfRmUe2O9l6NYuc10QzPaNxnkyIwa5698suNUPxGlEOwvm/h5oPeFcuxAWcgYYv5s589HWFrNjCF8EfOjZ4vU5oE1744EzxdmBiaGbeE8HDBXn1vK4owlcjawgQNF7KQ6LjSWr7xtARDF2IoKE4RYy0V0uVN4eAQ3zWRWWUt3cpYjTl34EZ9pO6CE8/If7noj75g0RYd/AHkIMdXBC4SlnNz+boLbba2ksIB+5z9jVILjvZwqx7i+k2filqZkVmasB/o2ChUFbdwg6c8DTOlyS/qB25dcfoCN2GF+cCAwEAAaMhMB8wHQYDVR0OBBYEFGKpXQNrF5IoxS6bL4F92+gxOJlIMA0GCSqGSIb3DQEBCwUAA4IBAQA3HgW5SoHlvvQVxqqi+mtscDZLhNfe13iG/nx8Er5il82b79RVydNs+f9sYxc4T4ctnrZu7x5e7jInJedNdAlrPorBdw+SfvKJsmiNndXugMew1FlcQTQVIFDCbziaJav8rKyMxPfeKkc1aixbajWZkKg6OPmmJn2ceTocbn8PMQy20xNvcWUwgF5FZZIuPqu6feOLJcUIYw+0JFZ265xka30QXpmytcIxajIzpD4PRdCIBuVSqgXacAs4t4+w+OhnosD72yvXck8M4GwX1j+vcuyw0yhDGNMmqsHWP7H3jnJiGDrKhhdVyplzDhTfv2Whbv/dIDn+meLE3yyC5yGL"
            ],
            "issuer": "https://login.microsoftonline.com/{tenantid}/v2.0"
        }

In JJWT I've implemented the SigningKeyResolver interface and I am required to return an instance of RSAPublicKey to do the verification. The issue I'm having is creating that Key correctly from the JSON.

Do I start with the Modulus and Exponent?

BigInteger modulus = new BigInteger(1, Base64.decodeBase64(jsonKey.getN()));
BigInteger exponent = new BigInteger(1, Base64.decodeBase64(jsonKey.getE()));
publicKey = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus, exponent));

Do I start with the x5c, generate an X509Certificate object and pull the PublicKey from there?

CertificateFactory factory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) factory
          .generateCertificate(new ByteArrayInputStream(
           DatatypeConverter.parseBase64Binary(jsonKey.getX5c())));
publicKey = (RSAPublicKey)cert.getPublicKey();

Both approaches have proved fruitless.

If I generated the RSAPublicKey from the modulus and exponent should I be able to print the Base64Binary encoded key to match the x5c property? Maybe that's not how I should be validating.

I might be misunderstanding how to use this.

As always, any documentation is appreciated as well.

x5c contains the certification chain. The first certificate of the chain must match with the key value represented by the other values in the JWK, in this case n and e , therefore the public key extracted from x5c[0] and the one built with n and e must be exactly the same

JWK values are encoded in base64url, not in base64. Change

BigInteger modulus = new BigInteger(1, Base64.decodeBase64(jsonKey.getN()));
BigInteger exponent = new BigInteger(1, Base64.decodeBase64(jsonKey.getE()));

with

BigInteger modulus = new BigInteger(1, Base64.getUrlDecoder().decode(jsonKey.getN()));
BigInteger exponent = new BigInteger(1, Base64.getUrlDecoder().decode(jsonKey.getE()));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM