Java Callout to generate or validate JWTs with signing and/or encryption

A Java Callout for generating and validating JWTs is now available. The callout can be used to sign JWTs with HMAC or RSA algorithms. It can also be used to sign and then encrypt JWTs using AES and RSA based key management algorithms. In short, JSON Web Signing and JSON Web Encryption is supported. The implementation uses jose4j JWT library for signing and encryption algorithms.

Sample Java callout policy to generate a signed and then encrypted JWT is given below. Here the claims-json is updated with iss, aud and expiry (in minutes) properties. It is then signed with HMAC_SHA512 algorithm. Finally, it is encrypted using AES_256_CBC_HMAC_SHA_512 algorithm. For the final step, encryption/signing key is determined using a public key with RSA_OAEP key management algorithm.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<JavaCallout async="false" continueOnError="false" enabled="true" name="JC-JWTGenerate">
    <DisplayName>JC-JWTGenerate</DisplayName>
    <FaultRules/>
    <Properties>
        <Property name="jws">true</Property>
        <Property name="jws-algo">HMAC_SHA512</Property>
        <Property name="jws-key">lr7LQmTSqre2v ... q7L1M/ZKJWhBLw==</Property>
        <Property name="jwe">true</Property>
        <Property name="jwe-algo">AES_256_CBC_HMAC_SHA_512</Property>
        <Property name="jwe-key-algo">RSA_OAEP</Property>
        <Property name="jwe-key">-----BEGIN PUBLIC KEY-----
MIIBIjAN ... PwIDAQAB
-----END PUBLIC KEY-----</Property>
        <Property name="claims-json">{"sub":"John Doe","email":"johndoe@gmail.com"}</Property>
        <Property name="iss">issuer-name</Property>
        <Property name="aud">audience-1</Property>
        <Property name="expiry">300</Property>
    </Properties>
    <ClassName>com.apigeecs.jwt.JWTGenerator</ClassName>
    <ResourceURL>java://edge-jwt-generate.jar</ResourceURL>
</JavaCallout> 

The JWTs generated above or by any OpenID Connect provider with same signing and encryption algorithm and private key, can be validated using the below Java Callout policy.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<JavaCallout async="false" continueOnError="false" enabled="true" name="JC-JWTGenerate">
    <DisplayName>JC-JWTGenerate</DisplayName>
    <FaultRules/>
    <Properties>
        <Property name="jws">true</Property>
        <Property name="jws-algo">HMAC_SHA512</Property>
        <Property name="jws-key">lr7LQmTSqre2v ... q7L1M/ZKJWhBLw==</Property>
        <Property name="jwe">true</Property>
        <Property name="jwe-algo">AES_256_CBC_HMAC_SHA_512</Property>
        <Property name="jwe-key-algo">RSA_OAEP</Property>
        <Property name="jwe-key">-----BEGIN PUBLIC KEY-----
MIIBIj ... PwIDAQAB
-----END PUBLIC KEY-----</Property>
        <Property name="jwt">eyJhbGc ... eXk57TblVQ</Property>
        <Property name="iss">issuer-name</Property>
        <Property name="aud">audience-1</Property>
    </Properties>
    <ClassName>com.apigeecs.jwt.JWTValidator</ClassName>
    <ResourceURL>java://edge-jwt-validate.jar</ResourceURL>
</JavaCallout> 

Flow variables can also be used to specify property values. For details see https://github.com/gahana/edge-jwt-sample

This callout only deals with JWT generation and validation tasks and is not a full OpenID Connect implementation. For a general treatment of OpenID Connect implementation on Edge, look at https://github.com/apigee/iloveapis2015-jwt-jwe-jws. So what is the need for a separate JWT implementation? The OpenID Connect implementation done very early in JWT spec/library days used nimbus library for some of the flows and this needed security exceptions on Edge to run the Java Callout. The above implementation aims to provide a Java callout without the need for any security exceptions on Edge. It achieves this by using minimal dependencies while providing both signing and encryption capabilities.

Comments
chandrasekharg0
New Member

Does this callout support encrypted private keys?

dchiesa1
Staff

This post is quite old.

The GenerateJWT policy, builtin to Edge, supports the use of encrypted private keys - basically all encryption supported by openssl. Reference. Therefore I recommend that you do not attempt to use the callout referenced here. Just use the builtin policy.

Also unlike the Java callout referenced here, the builtin policy will soon support ES, PS, RS, and HS algorithms. Expected release to the public cloud is by 2019 March 31. Until then, your algorithm choices are RS and HS.

dchiesa1
Staff

The [other implementation] done very early in JWT spec/library days used nimbus library for some of the flows and this needed security exceptions on Edge to run the Java Callout.

This is no longer true; the Java callout from https://github.com/apigee/iloveapis2015-jwt-jwe-jws does not require special exceptions to run. It actually works.

Even so, customers should not use it. They should use the builtin policies: GenerateJWT and VerifyJWT. They are easier to use, faster to execute at runtime, and they have better features!

chandrasekharg0
New Member

Thanks for the quick response.

We are using signed+encrypted JWT tokens for security. Currently edge does not have any out of box policies to support that. So i am using this callout .

When i am using privatekey with out encryption, the callout is working fine. But when I try with the encrypted private key, the callout is throwing the following error

Invalid JWS private key

I am using the following commands to generate the keys

openssl genrsa -out privatekey.pem 2048
openssl rsa -in privatekey.pem -out publickey.pem -pubout
openssl pkcs8 -in privatekey.pem -topk8  -out privatekey-pkcs8.pem
ssudhindra
Staff

Is the password specified correctly in `jws-key-pass` property?

You can debug with method `this.debugMessage`. Look for methods `getJWSKey` > `getDERPrivateKeyFromPEM`.

chandrasekharg0
New Member

Thanks for the response. We are facing one more issue when sending multiple requests using Jmeter/postman. The callout is not decrypting the token. For example for every 1000 requests, the callout is not decrypting the token for atleast 10 requests.

dchiesa1
Staff


Maybe you should:?

  • ask a new question since this seems to be a new issue
  • file an issue on gahana's github repo
Version history
Last update:
‎08-04-2017 09:06 AM
Updated by: