JWT Key encryption using RSA-OAEP-256

amotupalli
Participant I

We are facing EJT error as below

ejt_error : AES/GCM/NoPadding decryption failed: Tag mismatch!

Can anyone please help on this.

Thank You,

Lakshmi.

EDITED

We are trying to JWT encrypted the data using below code

Client :

String accessToken = getPrudentialAccessToken(); // AccessToken
logger.debug("Plain Payload  : " + checkKycRequest.toString());
checkKycRequest.setTaxStatus("01");
checkKycRequest.setIsNewVersion("FTM");
checkKycRequest.setFirstPan("BDJPA0600D");
String jsonObject = new Gson().toJson(checkKycRequest);
logger.debug(jsonObject);
jsonObject = generatePublicKeyRsaInputEncryption(jsonObject);
logger.debug(jsonObject);
HttpEntity<String> entity = new HttpEntity<>(updateObjWithEmptyStrings(jsonObject, true),
                                        IciciPrudentialUtils.getHeader(accessToken));
String fullUrl = config.getOauthUrls().getCheckKyc();
logger.debug(fullUrl);
RestTemplate template = new RestTemplate();
ResponseEntity<String> tranResponseEntity = template.exchange(fullUrl, HttpMethod.POST, entity,
  String.class);

Encryption :

public static String getEncryptWithPublicKey(String payload) {
        JWEAlgorithm alg = JWEAlgorithm.RSA_OAEP_256;
        EncryptionMethod encryptionMethod = EncryptionMethod.A256GCM;
        try {
                RSAPublicKey key = readPublicKey();
                JWEObject jwe = new JWEObject(new JWEHeader(alg, encryptionMethod), new Payload(payload));
                jwe.encrypt(new RSAEncrypter(key));
                return jwe.serialize();
        } catch (Exception e) {
                logger.debug(e.getMessage());
        }
        return null;
}
public static RSAPublicKey readPublicKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
    String key = new String(readFileBytes("public.key.prudential"), Charset.defaultCharset());
    String publicKeyPEM = key.replace("-----BEGIN PUBLIC KEY-----", "").replaceAll(System.lineSeparator(), "")
                                .replace("-----END PUBLIC KEY-----", "").replaceAll("\\s+", "");
    byte[] decoded = Base64.getDecoder().decode(publicKeyPEM);
    X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    return (RSAPublicKey) keyFactory.generatePublic(spec);
}
public static byte[] readFileBytes(String key) throws IOException {
    return Files.readAllBytes(Paths.get(Utils.loadPropertiesWithStaticProperty(key)));
}

When we are trying to decrypt the above encrypted data output using java callout. We are using the below xml code of java callout policy

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<JavaCallout name="Java-Callout-2">
    <Properties>
        <Property name="key-encryption">RSA-OAEP-256</Property>
        <Property name="content-encryption">A256GCM</Property>
        <Property name="debug">true</Property>
        <Property name="source">request.content</Property>
        <Property name="private-key">{private.my_private_key}</Property>
    </Properties>
    <ClassName>com.google.apigee.edgecallouts.VerifyEncryptedJwt</ClassName>
    <ResourceURL>java://something-here.jar</ResourceURL>
</JavaCallout>

While executing the API we are facing issue

ejt_error : AES/GCM/NoPadding decryption failed: Tag mismatch!

Thank You,

Lakshmi Motupalli

0 4 1,889
4 REPLIES 4

Hi

I'd be glad to try to help but you will need to provide much more information before I can even begin trying.

I am not looking at your screen. I cannot see what you are doing. I don't know what callout you're using or how you have configured it. One way I try to help people is by trying to reproduce the error or condition they are seeing, but I can't do that because you haven't provided any information to help me.

I don't know how you generated the encrypted JWT originally. I don't know what other things you've tried, to diagnose this yourself. I don't know anything about what you're doing except that there's an error that tells you "tag mismatch".

If you provide more information I might be able to help.

I'm sorry to hear you're having trouble. Thanks for providing the code you used to generate the encrypted JWT, and the configuration you used to decrypt. That makes it much easier for me to help you.

I just tried your code myself, and it works, with no error. I can generate an eJWT with your code, and I can decrypt it with the eJWT Java callout at this repo.

Are you sure that the encrypted JWT you are passing to the callout has not been modified after generation?

I can reproduce the error you reported, if I take a bonafide encrypted JWT, and replace the final two characters, with two other characters. And then try to decrypt it with the private key. The Java callout returns the exact error you reported.

Some background: encrypted JWT when serialized into compact form (the most common form), have 5 parts:

  • Protected Header.
  • Encrypted Key.
  • Initialization Vector.
  • Ciphertext. (encrypted payload)
  • Authentication Tag.

Each of these parts is a base64-encoded string. The final part is the authentication tag. This is used to validate the decryption against some forms of attack. If you modify the auth tag, then try to decrypt that modified eJWT, the tag check will fail, as it should, and you will see the error message you have reported.

BTW I noticed you are using the older classname, com.google.apigee.edgecallouts.VerifyEncryptedJwt .

I suggest that you pull the latest version of the repo. If you do that, you will see the classname is updated to com.google.apigee.callouts.VerifyEncryptedJwt.

And the jar name for the latest is

apigee-callout-encrypted-jwt-20210428.jar

@Adilakshmi Motupalli - did my response help?