'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 |
