Decrypt JWE

APPLE PAY WALLET

Cardinal Cruise utilizes a JWE to handle encryption and to assist in passing secure data between you and Cardinal. As of writing, typically JWE's are only being used in wallet type payment brands like Apple Pay or Visa Checkout to transmit card details from Cardinal to the merchant. The JWE must be sent server-side for decryption. Decrypting a JWE client-side is not a valid activation option.

The JWE is used as the method of transmitting encrypted payment data as a custom claim within a Cardinal Cruise response JWT. The examples below will reflect the passing of credit card data within our SecuredData object. Please be aware that the specific payment data passed in the SecuredData object will depend on the individual payment brand. The encryption and decryption process will remain the same regardless of the data being sent.

Symmetric Key

The JWE requires a symmetric encryption key to use for encrypting a one time use encryption key that is returned on the JWE. This one time use key is then decrypted by the receiver of the JWE using the common key. Upon merchant registration a AES 256 symmetric key will be generated by Cardinal along with your API key and shared with you. The symmetric key will allow the holder to access any data encrypted with that key. As such, it should be treated similarly to your API key - as a shared secret between Cardinal and the merchant. The symmetric key is tied to the API Key so that when an API Key is rotated the symmetric key will be rotated as well.

The contents of a JWE may differ for each place a JWE is used. JWE's are simply a vehicle to return back sensitive information of any kind. The Payload claim of the decrypted JWE will always be wrapped in a generic 'SecuredData' object. The SecuredData object will contain the sensitive information being returned. A common use case for JWE's is using a wallet payment brand. In this case the SecuredData object would have 1 child object, an Account object that describes the credit card details the consumer picked to use at the wallet. Below is an example of the JSON content of a wallet JWE Payload claim:

JWE Payload
{
	"SecuredData": {
		"Account": {
			"AccountNumber": "1234..32",
			"ExpirationMonth": "02",
			"ExpirationYear": "2020"
			"NameOnCard": "John Doe"
		}
	}
}

The JWE will be sent back on the response JWT within the payload on a new 'JWE' field. Below is a sample JSON object that represents the data structure of the JWT and JWE:

JWT Claims
{
	"jti": "29311a10-5048-11e6-8c35-8789b865ff15",
	"iat": 1448997875,
	"iss": "56560a358b946e0c8452365ds",
	"OrgUnitId": "565607c18b946e058463ds8r",
	"Payload": {
		...
		"JWE": "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGeipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDbSv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaVmqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je81860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi6UklfCpIMfIjf7iGdXKHzg.48V1_ALb6US04U3b.5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6jiSdiwkIr3ajwQzaBtQD_AXFBoMYUZodetZdvTiFvSkQ"
	}"
}


Code Samples

Below are samples of decryption JWT's in a few different languages.

Java

We recommend using an existing third party library to assist you in decrypting the JWE. The JWT.io website contains a list of approved libraries, with their feature sets. Check it out here.

JWE Decryption Example
// This sample code was written using the Jose4j
// library (https://bitbucket.org/b_c/jose4j/wiki/Home) found at JWT.io

import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jwk.JsonWebKey;
import org.jose4j.lang.JoseException;

private String decryptJwe(String encryptedJwe) throws JoseException { 
 
 
    String key = "xeBVa77hvlGhRpOlAtB6Mbupkfclxv91S4AMNmfLiWU=";  //test value
     
    String jwkJson = "{\"kty\":\"oct\",\"k\":\"" + key + "\"}";
    JsonWebKey jwk = JsonWebKey.Factory.newJwk(jwkJson);
     
    JsonWebEncryption receiver = new JsonWebEncryption();
    receiver.setCompactSerialization(encryptedJwe);
    receiver.setKey(jwk.getKey());
     
    return receiver.getPlaintextString();
}