On This Page
FILTER BY TAG
Construct Messages Using JSON Web Tokens
IMPORTANT
As of
February 2026
, there are new requirements for
constructing a JWT. This section explains how to update your system to remain in
compliance. By September 2026
, all merchants using HTTP signature messaging must
migrate to JSON Web Token (JWT) messaging in order to support message-level encryption
(MLE).This figure shows the steps required for using JSON Web Tokens (JWTs) to construct messages.
Each step is described in the following subsections.
JSON Web Token Message Elements
A JWT message consists of HTTP headers and an HTTP message body.
- HTTP Message Elements
- Your HTTP message header must include these elements:
- HTTP Message Header ElementsHTTP Header ElementDescriptioncontent-typeAlso known as the Multipurpose Internet Mail Extension (MIME) type, this element identifies the media or file type of the resource (application/json).hostThe transaction endpoint. (nabgateway-developer.nab.com.au)authorizationJSON Web Signature (JWS) bearer token.
- HTTP Message Body
- Your API request.
Step 1: Set Known HTTP Headers
Set the values for these HTTP header elements. They do not require calculation.
- content-type
- Set to the media or file type resource.
- host
- Set to the endpoint.
Step 2: Set the JWS Header Claims
You must construct a
JSON Web Signature
(JWS) token. To construct a JWS token, you
must first set its header claim values.These header claim values do not require calculation.
Header Field | Description |
|---|---|
alg | The symmetric algorithm you use to sign the token header. These
algorithms are supported:
|
kid | The ID of the key you use to digitally sign the JWT.
The
key ID must be registered with the authorizing server. It is the key ID
from your shared secret key pair. For more information, see Create a Shared Secret Key Pair. |
typ | The token type. Set to JWT . |
Step 3: Set the JWS Body Claims
After you set the JWS header values, set these JWS body claim values:
digest | A Base64-encoded hash of the message payload. Do not include the digest field if the request message
is empty, such as during a GET or DELETE request. | String |
digestAlgorithm | The algorithm used to hash the message payload. The message payload should be hashed using the SHA-256
algorithm. Do not include the digestAlgorithm field if the
digest field is not included. | String |
exp | The time at which the JWS token expires. Field values cannot
exceed two minutes after the message issue date, which is the
iat field value. This field is an HTTP-date value as
defined in RFC7231.For example, 01/01/2020 at 00:02:00 is
1577836920 . | String |
iat | The date and time at which the message is issued. This field
uses a NumericDate value as defined in RFC 7519, which is
the number of seconds since
1970‑01‑01T00:00:00Z (Unix epoch).For
example, 01/01/2020 at 00:00:00 is
1577836800 . | String |
iss | The issuer identifier for the JWS token.
Set
to the key ID that created the shared secret key pair.
This value is used to validate the issuer. | String |
jti | The unique token ID. This value is used for replay
prevention. Format the value using UUID version 4. For
example:
6643fb9a-8093-47c6-95d3-8d69785b5e62 | String |
request-method | The HTTP request method. For example, post ,
get , put ,
patch , or delete .It is
standard practice to use lowercase values. | String |
request-resource-path | The complete URL path for the HTTP request. It is standard
practice to use lowercase values. | String |
v-c-jwt-version | The Visa JWT scheme version number. Set to
2 . | String |
v-c-merchant-id | Your National Australia Bank transacting merchant ID
(MID).If you are a portfolio or merchant account user,
set this to the transacting merchant ID you send requests on
behalf of. | String |
v-c-response-mle-kid | The message-level encryption response key ID, also known as
the REST–API Response MLE key. | String |
The value of the
digest
JWS claim is a hashed version of the HTTP
message body that you must calculate. National Australia Bank
uses this hash
value to validate the integrity of your message body.Follow these steps to calculate the digest hash:
- Generate the SHA-256 hash of the JSON payload (message body).
- Encode the hashed string to Base64.
- Add the message body hash to thedigestJWS body claims.
- Add the algorithm used to hash the digest in thedigestAlgorithmJWS body claims.
Example: Creating a Message Hash Using the Command Line
shasum
Toolecho -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
Example: Creating a Message Hash Using the Command Line
base64
Toolecho -n "6ae5459bc8a7d6a4b203e8a734d6a616725134088e13261f5bbcefc1424fc956" | base64
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 = "SHA-256=" + digest; } return digest; }
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 "SHA-256=" + Base64.getEncoder().encodeToString(digest); }
Step 4: Calculate the JWS Signature
You can now calculate the JSON Web Signature (JWS). The JWS consists of the JWS header and
claim set hashes in the following format. They are encrypted with the private key.
[JWS Header].[Claim Set]
Follow these steps to calculate the signature:
- Concatenate the JWS header and claim set hash strings with a period character (.) between the hashes:[JWS Header].[Claim Set]
- Generate an encoded version of the text file using your shared secret key from the key pair. For more information, see Create a Shared Secret Key Pair.
- Base64-encode the signature output.
- After calculating the signature, you can construct a complete JWS token by combining the JWS header claims, body claims, and signature.
Example: Encoding Headers and Body
printf "%s.%s" \ "$(echo -n '{"alg":"HS256","typ":"JWT","kid":"1234567890"}' | base64 | tr -d '\n' | tr '+/' '-_' | tr -d '=')" \ "$(echo -n '{"digest":"Yjg0NGIxOTMxMzQ2NzhlYjdiMDdhMWZmYjZiYzUzNzlkMTk5NzFmNjAzNWRmMThlNzk0N2NhY2U0YTEwNzYyYQ==","digestAlgorithm":"SHA-256","iat":1709845200,"exp":1709845320,"request-method":"post", "request-resource-path":"/pts/v2/payments","request-host":"api.cybersource.com","iss":"merchantid","jti":"12345678-1234-1234-1234-123456789012","v-c-jwt-version":"2","v-c-merchant-id":"merchantid"}' | base64 | tr -d '\n' | tr '+/' '-_' | tr -d '=')" \ > signing_input.txt
Code Example: Encoding the Signature File Using OpenSSL
Generate the HMAC signature using the openssl tool and the signing_input.txt
generated above. The tr commands convert standard Base64 output to Base64URL
encoding as required by JWT specification RFC 7515.
openssl dgst -sha256 -mac HMAC -macopt key:"$(echo 'YOUR_BASE64_ENCODED_SECRET' | base64 -d)" -binary signing_input.txt | base64 | tr -d '\n' | tr '+/' '-_' | tr -d '='
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.