0

I am using nimbus-jose-jwt library in Android to generate encrypted JWT (JWE), to send it in the body of an APIGEE API.

I have used the following code to generate encrypted JWT:

public class EncryptedJWTGenerator {
    String jweString;
    Map<String, Object> map = new HashMap<>();

    @RequiresApi(api = Build.VERSION_CODES.O)
    public EncryptedJWTGenerator() throws NoSuchAlgorithmException, JOSEException, InvalidKeySpecException {

        String publicKey = <my_public_key>;

        try {
            // create Gson instance
            Gson gson = new Gson();

            URL url = getClass().getResource("Payload.json"); //JSON file having the Payload

            // create a reader
            Reader reader = Files.newBufferedReader(Paths.get(url.toURI().getPath()));

            // convert JSON file to map
            map = gson.fromJson(reader, Map.class);

            // print map entries
            for (Map.Entry<?, ?> entry : map.entrySet()) {
                System.out.println(entry.getKey() + "=" + entry.getValue());
            }

            // close reader
            reader.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        JWEAlgorithm alg = JWEAlgorithm.RSA_OAEP_256;
        EncryptionMethod enc = EncryptionMethod.A256GCM;


        byte[] publicBytes = Base64.decodeBase64(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey pubKey = keyFactory.generatePublic(keySpec);

        // Generate the preset Content Encryption (CEK) key
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(EncryptionMethod.A256GCM.cekBitLength());

        SecretKey cek = keyGenerator.generateKey();

        JOSEObjectType joseObjectType = new JOSEObjectType("JWT");
        JWEHeader jweHeader = new JWEHeader(alg, enc, joseObjectType, null, null, null, null, null, null, null, null, null, null,
                null, null, null, null, 0, null, null, null, null);

        // Encrypt the JWE with the RSA public key + specified AES CEK
        JWEObject jweObject = new JWEObject(new JWEHeader(jweHeader), new Payload(map));

        jweObject.encrypt(new RSAEncrypter((RSAPublicKey) pubKey, cek));

        jweString = jweObject.serialize();
    }
}

But when I use this JWE in the body of the API, I get the following response:

{
    "Code": 0,
    "Response": {},
    "Message": "Mandatory Fields are missing"
}

But when I use this tool -> https://dinochiesa.github.io/jwt/ to generate the JWE and use it with the APIGEE API, it works fine.

Am I missing something in my code for JWE generation?

Sparsh Dutta
  • 2,450
  • 4
  • 27
  • 54

1 Answers1

0

Solved it by passing my JSON as String for Payload instead of reading from file and converting to map and passing it for Payload.

Replaced JWEObject jweObject = new JWEObject(new JWEHeader(jweHeader), new Payload(map)); with:

 JWEObject jweObject = new JWEObject(new JWEHeader(jweHeader), new Payload(<my_json_string>));
Sparsh Dutta
  • 2,450
  • 4
  • 27
  • 54