Over the past 3 years or so working in a software team that develops APIs/integrations between many complex systems, we’ve seen the rise of the JSON Web Token. This humble little block of base64 encoded data is now at the core of most every API we build, and is heavily used in enforcing confidentiality and integrity in many different ways in our landscape.
CA’s API Gateway product includes functionality out of the box to handle JSON Web Tokens. But it comes with some nuances. Having been the API Gateway SME across many projects, I’ve had to decipher every bit of how CA’s mysterious JSON assertions work.
Public & Private Keys
First things first. Not all public keys are made equal! CA’s product is unable to ingest RSA public keys for use in JWTs; it currently only gives you the option to use a public key where you have a corresponding private key installed (wtf mate), or you have a valid x509 certificate for (eg. SSL)… This is hardly useful.
To get around this, we use this little snippet to convert a perfectly good RSA public key into a JWK format – (.NET Core C#) Get RSA Public Key in JWK Format (JSON Web Key). To use this in the CA gateway, we wrap the JWK into a JWKS format, creating a JSON array of keys, and storing this in a context variable. This context variable is then referenced in the Encode/Decode Json Web Token assertion.
Next; JWKS keys can have multiple uses; in the case of CA, the key use MUST be specified, and it is not appropriate to simply state that the use is for encryption AND signing; instead, if a key is usable for both, you must create two keys within the JWKS with all things equal, and set the use value to ‘enc’ or ‘sig’ appropriately.
The result of both of these actions is shown below:
{
"keys": [
{
"e": "AQAB",
"kty": "RSA",
"alg": "RS256",
"n": "uObuBVbjcjxgv8cfRc3......",
"use": "sig",
"kid": "3494b1e786cdad092e423766bbe37f54ed87b22d"
},
{
"alg": "RS256",
"n": "uObuBVbjcjxgv8cfRc3......",
"use": "enc",
"kid": "60f4060e58d75fd3f70beff88c794a775327aa31",
"e": "AQAB",
"kty": "RSA"
}
]
}
Combining JWS & JWE
Creating JWT’s that are both signed and encrypted is actually simple with the CA API Gateway. Unfortunately, the reverse is complex as CA poorly documents that you must do this in multiple steps; unlike creating a JWS/JWE token, there is not a single assertion approach for the reverse.
The process is as follows:
1. Decode Json Web Token
- Decrypts the token; specify the private key to use to decrypt
- The output is an unencrypted signed JWT (JWS)
- Use the ${decryptedPayload.plaintext} variable to reference the unencrypted JWT
2. Decode Json Web Token (again)
- Verifies the signature of the JWT (JWS)
- Use a JWKS for the recipient key!
- Use ${output.payload} to reference the data in the token
- “Fail on invalid signature” should
View Comments (1)
Great post!!! Thanks for sharing The Emperor :)