'Verification of ID token using FusionAuth- JWT library, getting PEMDecoderException: "Unexpected PEM Format"

I am using fusionauth-jwt library to verify ID token signed by RSA SHA 256 key. In my code below ,first trying to get public key using JWKS json and then trying to create a Verifier instance so that I can verify my id token.

List<JSONWebKey> keys = JSONWebKeySetHelper.retrieveKeysFromJWKS("http://localhost:9011/.well-known/jwks.json");

        Map<String, Verifier> publicKeyVerifiers = new HashMap<String,Verifier>();
        for (JSONWebKey key : keys) {
            String publicKey = key.x5c.get(0); //getting x5c element
            Verifier verifier = RSAVerifier.newVerifier(publicKey); // Creating RSA verifier instance where getting issue
            String kid = key.kid;
            publicKeyVerifiers.put(kid, verifier);
        }

JWT jwtDecoded = JWT.getDecoder().decode(idToken, publicKeyVerifiers);

Getting issue at the time of creating verifier instance because the x5c element contains Base64Encoded value and not the .pem format value which begins with "-----BEGIN"

Class "io.fusionauth.pem.PEMDecoder.java" expects "-----BEGIN" which is not present in key.x5c and hence throwing exception "throw new PEMDecoderException(new InvalidParameterException("Unexpected PEM Format"));

Portion of code from "io.fusionauth.pem.PEMDecoder.java"

public PEM decode(String encodedKey) {
        Objects.requireNonNull(encodedKey);

        try {
            if (encodedKey.contains("-----BEGIN RSA PUBLIC KEY-----")) {
                return this.decode_PKCS_1_Public(encodedKey);
            } else if (encodedKey.contains("-----BEGIN PUBLIC KEY-----")) {
                return this.decode_X_509(encodedKey);
            } else if (encodedKey.contains("-----BEGIN CERTIFICATE-----")) {
                return new PEM(CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(this.getKeyBytes(encodedKey, "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----"))));
            } else if (encodedKey.contains("-----BEGIN RSA PRIVATE KEY-----")) {
                return this.decode_PKCS_1_Private(encodedKey);
            } else if (encodedKey.contains("-----BEGIN PRIVATE KEY-----")) {
                return this.decode_PKCS_8(encodedKey);
            } else if (encodedKey.contains("-----END EC PRIVATE KEY-----")) {
                return this.decode_EC_privateKey(encodedKey);
            } else {
                throw new PEMDecoderException(new InvalidParameterException("Unexpected PEM Format"));
            }
        } catch (InvalidKeyException | InvalidKeySpecException | IOException | NoSuchAlgorithmException | CertificateException var3) {
            throw new PEMDecoderException(var3);
        }
    }


Solution 1:[1]

You should be able to take the first element of the x5c JWK property and simply add the PEM envelope around it.

-----BEGIN CERTIFICATE-----
...x5c[0]
-----END CERTIFICATE-----

This will produce a valid X.509 encoded PEM certificate. Just make sure to add new lines after -----BEGIN CERTIFICATE----- and before -----END CERTIFICATE-----.

This ought to be enough. If it isn't, splitting the x5c[0] every 64 octets with a newline would be the next step.

-----BEGIN CERTIFICATE-----
...x5c[0]{0,64}
...x5c[0]{64,128}
...etc
-----END CERTIFICATE-----

If that fails, the x5c[0] is not encoded as specified in the first place.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Filip Skokan