Construct Messages Using JSON Web Tokens

Follow these steps to construct messages using JWTs:

Generate a Hash of the Message Body

Generate a Base64-encoded SHA-256 hash of the message, and place the hash in the header's
digest
field. This hash is used to validate the integrity of the message at the receiving end.
Follow these steps to generate the hash:
  1. Generate the SHA-256 hash of the JSON payload (body of the message).
  2. Encode the hashed string to Base64.
  3. Add the message body hash to the
    digest
    payload field.
  4. Add the hash algorithm used to the
    digestAlgorithm
    payload field.
Example: Digest Header Field
digest: RBNvo1WzZ4oRRq0W9+hknpT7T8If536DEMBg9hyq/4o=
Example: DigestAlgorithm Header Field
digestAlgorithm: SHA-256
Code Example: Creating a Message Hash Using C#
public static string GenerateDigest() { var digest = ""; var bodyText = "{ your JSON payload }"; using (var sha256hash = SHA256.Create()) { byte[] payloadBytes = sha256hash .ComputeHash(Encoding.UTF8.GetBytes(bodyText)); digest = Convert.ToBase64String(payloadBytes); digest = digest; } return digest; }
Code Example: Creating a Message Using Java
public static String GenerateDigest() throws NoSuchAlgorithmException { String bodyText = "{ your JSON payload }"; MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(bodyText.getBytes(StandardCharsets.UTF_8)); byte[] digest = md.digest(); return Base64.getEncoder().encodeToString(digest); }

Generate the Token Header

The token header is encrypted with a URL safe base64 algorithm. These three header fields must be included in the header.
Token Header Fields
Token Header Field
Description
kid
The ID of the key used to digitally sign the JWT.
alg
Algorithm used to sign the token header.
v-c-merchant-id
Merchant ID used in the request transaction. To obtain the merchant ID, see Step 1: Sign Up for a Sandbox Account.
Token Header
eyJ2LWMtbWVyY2hhbnQtaWQiOiJtZXJjaGFudElEIiwiYWxnIjoiUlMyNTYiLCJraWQiOiI3MDc4NjMzMjg1MjUwMTc3MDQxNDk5In0
Generating the Token Header with Python
Encode the header data and then remove any padding added during the encryption process.
import base64 # open file in binary mode data = b'{"v-c-merchant-id":"merchantID","alg":"RS256","kid":"7078633285250177041499"}' encoded = base64.urlsafe_b64encode(data) stripped = encoded.decode('ascii').strip('=') print(stripped)

Generate a Hash of the Claim Set

Generate a Base64-encoded SHA-256 hash of these header fields:
Headers
Header Field
Description
iat
The date and time of the message origin. Date formatting is defined by RFC 7231, Section 7.1.1.1.
digest
A Base64 encoded hash of the message payload.
The
digest
field is not included in a GET request.
digestAlgorithm
The algorithm used to hash the message payload.
The message payload should be hashed using the SHA-256 algorithm.
The
digestAlgorithm
field is not included in a GET request.
Follow these steps to generate the hash:
  1. Generate the SHA-256 hash of the fields in JSON format.
  2. Encode the hashed string to Base64.
  3. Add the message body hash to the
    digest
    header field.
Creating a Message Hash Using Command Line Tools
Generate the SHA-256 hash using the
shasum
tool.
echo -n "{"iat":"Thur, 15 June 2017 08:12:31 GMT","digest":"tP7hDajF4f6q0ysBQCHgef5K/PBq8iMASvlEARp8tl=", "digestAlgorithm":"SHA-256"}" | shasum -a 256
Base64 Encoding a Message Hash Using Command Line Tools
Generate the SHA-256 hash using the
base64
tool.
echo -n "5995a4f27b4b9256a94cf54489a9ef691d8dc8a590d322780d3b202cfa2f078f" | base64
Add the message body hash to the
digest
header field
NTk5NWE0ZjI3YjRiOTI1NmE5NGNmNTQ0ODlhOWVmNjkxZDhkYzhhNTkwZDMyMjc4MGQzYjIwMmNmYTJmMDc4Zg==

Generate a Hash of the Token Header

Generate a Base64-encoded SHA-256 hash of these header fields:
Token Headers
Token Header Field
Description
kid
The ID of the key used to digitally sign the JWT.
alg
Algorithm used to sign the token header.
v-c-merchant-id
Merchant ID used in the request transaction.
Follow these steps to generate the hash:
  1. Generate the SHA-256 hash of the fields in JSON format.
  2. Encode the hashed string to Base64.
Create a Message Hash Using the
shasum
Command Line Tool
echo -n "{"kid":"cc34c0a0-bd5a-4a3c-a50d-a2a7db7643df", "alg":"RS256","v-c-merchant-id":"merchant_id"}" | shasum -a 256
Create a Message Hash Using the
base64
Command Line Tool
echo -n "a9953cdca19433ae5ec1c4eb0dafd41df6de4d20cd47cbace3c316a1ac6d2008" | base64

Example: Token Header Hash

NTc3N2RlOTAyZWEwNWU0NWM2YTBkNTI4Mjg0YTJmOTVlZGYxYWJlMzBjNzk5OTg1YzEzMjNiMDkzMzc0MWEwNA==

Generate the Message Body

Encode the message body (payload) using URL safe Base64 encryption. At a minimum, the body should include these fields:
Message Body Fields
Message Body Field
Description
digest
A base64 encoded SHA-256 has of the claim set.
digestAlgorithm
Algorithm used to sign the JWT.
iat
Time the JWT was issued.
Follow these steps to generate the hash:
  1. Generate the SHA-256 hash of the JSON payload (body of the message).
  2. Encode the hashed string to Base64.
  3. Add the message body hash to the
    digest
    header field.
  4. Add the hash algorithm used to the
    digestAlgorithm
    header field.
Encrypted Message Body
Line break added for readability.
digest: eyJkaWdlc3QiOiJSQk52bzFXelo0b1JScTBXOStoa25wVDdUOElmNTM2REVNQmc5aHlxLzRvPSIsImRpZ 2VzdEFsZ29yaXRobSI6IlNIQS0yNTYiLCJpYXQiOiIyMDI0LTA0LTA1VDE2OjI1OjE4LjI1OVoifQ
Encrypting Message Body Using Python
Generate the SHA-256 hash using the
shasum
tool. Line break on line three added for readability.
import base64 data = b'{"digest":"RBNvo1WzZ4oRRq0W9+hknpT7T8If536DEMBg9hyq/4o=","digestAlgorithm":"SHA-256", "iat":"2024-04-05T16:25:18.259Z"}' encode = base64.urlsafe_b64encode(data) stripped = encode.decode('ascii').strip('=') print(stripped)

Generate a JSON Web Token

You can now build the JWT. The JWT is made up of the token header Base64 encoded hash, the payload Base64 encoded hash, and the JWT signature in the following format:
[Token Header].[Payload].[Signature]
To generate the JWT, concatenate the header, payload, and signature strings with a period (.) separating the hashes:
[[Token Header].[Payload].[Signature]
.
JSON Web Token
eyJ2LWMtbWVyY2hhbnQtaWQiOiJtZXJjaGFudElEIiwiYWxnIjoiUlMyNTYiLCJraWQiOiI3M Dc4NjMzMjg1MjUwMTc3MDQxNDk5In0.eyJkaWdlc3QiOiJSQk52bzFXelo0b1JScTBXOStoa2 5wVDdUOElmNTM2REVNQmc5aHlxLzRvPSIsImRpZ2VzdEFsZ29yaXRobSI6IlNIQS0yNTYiLCJ pYXQiOiIyMDI0LTA0LTA1VDE2OjI1OjE4LjI1OVoifQ.YjgwNGIxOTMxMzQ2NzhlYjdiMDdhM WZmYjZiYzUzNzliMTk5NzFmNjAzNWRmMThlNzk0N2NhY2U0YTEwNzYyYQ

Create the Authorization Header

You can now build the transaction header using a JSON Web Token.
Your message header must include these header fields:
JWT Header Fields
JWT Header Field
Description
Authorization
The bearer token generated. (Bearer<JWT>)
Content-Type
Also known as the Multipurpose Internet Mail Extension (MIME) type, this identifies the media or file type of the resource. (application/json)
Host
The transaction endpoint. (
api.cybersource.com
)
JSON Web Token Header
Host: api.cybersource.com Content-Type: application/json Authorization: Bearer eyJ2LWMtbWVyY2hhbnQtaWQiOiJtZXJjaGFudElEIiwiYWxnIjoiUlMyNTYiLCJraWQiOiI3M Dc4NjMzMjg1MjUwMTc3MDQxNDk5In0.eyJkaWdlc3QiOiJSQk52bzFXelo0b1JScTBXOStoa2 5wVDdUOElmNTM2REVNQmc5aHlxLzRvPSIsImRpZ2VzdEFsZ29yaXRobSI6IlNIQS0yNTYiLCJ pYXQiOiIyMDI0LTA0LTA1VDE2OjI1OjE4LjI1OVoifQ.YjgwNGIxOTMxMzQ2NzhlYjdiMDdhM WZmYjZiYzUzNzliMTk5NzFmNjAzNWRmMThlNzk0N2NhY2U0YTEwNzYyYQ

Elements of a JSON Web Token Message

A JWT message is constructed using HTTP headers and an HTTP message body.
HTTP Message Elements
Your HTTP message header must include these headers:
HTTP Message Headers
HTTP Header
Description
content-type
Also known as the Multipurpose Internet Mail Extension (MIME) type, this identifies the media or file type of the resource. (application/json)
host
The transaction endpoint. (
api.cybersource.com
)
authorization
JWS bearer token.
HTTP Message Body
Your API request.

Step 1: Set Known HTTP Headers

Set these HTTP header values that do not require calculation:
content-type
host

Step 2: Set the JWS Header Claims

You must construct a
JSON web signature
(JWS) token. To construct a JWS, you must first set its headers claims.
Set these JWS header claim values that do not require calculation.
HTTP Message Headers
Header Field
Description
v-c-merchant-id
Your
Cybersource
transacting merchant ID (MID).
If you are a portfolio or merchant account user, this is the transacting merchant ID that you are sending requests on behalf of.
alg
Algorithm used to sign the token header. These are the supported algorithms:
  • RS256 (default)
  • RS384
  • RS512
  • PS256
  • PS384
  • PS512
kid
The ID of the key used to digitally sign the JWT. The key ID (kid) must be registered with the authorizing server. This is the key ID from your P12 certificate. For more information, see Create a P12 Certificate.

Step 3: Set the JWS Body Claims

After setting the JWS headers, you must set these JWS body claim values:
JWS Body Claims
JWS Body Claim
Description
iat
The date and time of the message origin. Date formatting is defined by RFC 7231, Section 7.1.1.1.
digest
A Base64 encoded hash of the message payload.
The
digest
field is not included in a GET request.
digestAlgorithm
The algorithm used to hash the message payload.
The message payload should be hashed using the SHA-256 algorithm.
The
digestAlgorithm
field is not included in a GET request.
The value of the
digest
HTTP header is a hashed version of the HTTP message body that you must calculate. This hash value is used to validate the integrity of your message by the receiver.
Follow these steps to calculate the digest hash:
  1. Generate the SHA-256 hash of the JSON payload (message body).
  2. Encode the hashed string to Base64.
  3. Add the message body hash to the
    digest
    JWS body claims.
  4. Add the hash algorithm used to the
    digestAlgorithm
    JWS body claims.
Creating a Message Hash Using the Command Line
shasum
Tool
echo -n "{"clientReferenceInformation":{"code":"TC50171_3"},"paymentInformation":{"card":{"number": "4111111111111111","expirationMonth":"12","expirationYear":"2031"}},"orderInformation":{"amountDetails": {"totalAmount":"102.21","currency":"USD"},"billTo”:{“firstName":"John","lastName":"Doe","address1": "1MarketSt","locality":"sanfrancisco","administrativeArea":"CA","postalCode":"94105","country":"US", "email":"","phoneNumber":"4158880000"}}}" | shasum -a 256
echo -n "6ae5459bc8a7d6a4b203e8a734d6a616725134088e13261f5bbcefc1424fc956" | base64
Creating a Message Hash Using the Command Line
base64
Tool
echo -n "6ae5459bc8a7d6a4b203e8a734d6a616725134088e13261f5bbcefc1424fc956" | base64
Creating a Message Hash Using C#
public static string GenerateDigest() { var digest = ""; var bodyText = "{ your JSON payload }"; using (var sha256hash = SHA256.Create()) { byte[] payloadBytes = sha256hash .ComputeHash(Encoding.UTF8.GetBytes(bodyText)); digest = Convert.ToBase64String(payloadBytes); digest = "SHA-256=" + digest; } return digest; }
Creating a Message Using Java
public static String GenerateDigest() throws NoSuchAlgorithmException { String bodyText = "{ your JSON payload }"; MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(bodyText.getBytes(StandardCharsets.UTF_8)); byte[] digest = md.digest(); return "SHA-256=" + Base64.getEncoder().encodeToString(digest); }

Step 4: Calculate the JWS Signature

You can now calculate the JWS signature. The JWS signature is made up of the JWS header and claim set hashes in the following format, and encrypted with the private key.
[JWS Header].[Claim Set]
Follow these steps to calculate the signature:
  1. Concatenate the JWS header and claim set hash strings with a period character (
    .
    ) between the hashes:
    [JWS Header].[Claim Set]
  2. Generate an encoded version of the text file using your private key from the
    .p12
    certificate. For more information, see Create a P12 Certificate.
  3. Base64 encode the signature output.
  4. After calculating the signature, you can construct a complete JWS token by combining the JWS header claims, body claims, and signature.
Example: Token Signature Hash
YjgwNGIxOTMxMzQ2NzhlYjdiMDdhMWZmYjZiYzUzNzliMTk5NzFmNjAzNWRmMThlNzk0N2NhY2U0YTEwNzYyYQ
Code Example: Encoding the Signature File Using OpenSSL
Encode the signature file using the
openssl
tool.
openssl rsautl -encrypt -inkey publickey.key -pubin -in [signature-text-file] > [signature-encoded-file]
Code Example: Base64 Encoding the Signature File Using the Command Line
Encode the signature file using the
openssl
tool and remove any padding.
base64 -i [signature-encoded-file]

Step 5: Complete the Message with JWTs

Combine all of the HTTP headers with your HTTP message body to construct your HTTP signature message.
If you have not already, you must construct the entire JWS token by combining the JWS header claims, body claims, and signature from steps 2 – 4.