Object signing and encryption conforms to the IETF JSON Object Signing and Encryption (JOSE) standard, which provides a general approach for encrypting and signing any content. It includes the use of JSON Web Encryption (JWE) for encryption and JSON Web Signature (JWS) for signing. Visa uses it to protect sensitive information, such as personal information about cardholders and their accounts, e.g. account numbers (PANs).
Clients use Field-Level Encryption (FLE) or Message-Level Encryption (MLE) to encrypt sensitive data when making API request to Visa. Field-level encryption encrypts specific API data fields (values), while Message-Level encryption encrypts entire request message. API responses may also contain Visa- encrypted data, which a client must decrypt.
Note: In many cases, the use of Field-level encryption is indicated by the enc prefix on the API field name, e.g. encPaymentInstrument.
The JWE specification standardizes the way to represent encrypted content in a JSON-based data structure.
See https://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-40 for more details and complete specifications for JWE.
Visa supports both symmetric (JWE using API Key and Shared Secret) and asymmetric algorithms (JWE using RSA PKI).
For symmetric keys, the corresponding Key ID or API Key and shared secret are assigned to the client during onboarding. The shared secret will be generated and provided by Visa.
For asymmetric keys, during onboarding both Visa and the client would share their public keys. Client will encrypt all necessary fields in the request payload using Visa's public key and Visa will decrypt these fields using its corresponding private key. Similarly, Visa will encrypt all necessary fields in the response payload using the client's public key and client will decrypt these fields using their private key.
Refer to the product-specific API specification document or the implementation guide for more information on which type of encryption is required for the Visa product you are integrating with.
Visa uses the Compact serialization scheme for JWE. The JWE composition is defined as follows:
Base64URL (UTF8 (JWE Header)) || ‘.’ || Base64URL (JWE Encrypted Key) || ‘.’ || Base64URL (JWE Initialization Vector) || ‘.’ || Base64URL (JWE Ciphertext) || ‘.’ || Base64URL (JWE Authentication Tag)
Base64 encoding & conventions that Visa follows:
Visa has chosen to suffix “..” to the Base64URL encoded values, instead of the more popular == convention.
The JWE header contains the following metadata for encryption and decryption. Please refer to the corresponding product API specification for a different set of header fields to be provided.
Name |
Description |
alg | (Required) Description of the algorithm used to encrypt the randomly generated symmetric Content Encryption Key (CEK). Format: Values are AGCM256KW (Symmetric), RSA-OAEP-256 (Asymmetric). |
typ |
(Required) Media type of the JWE. JavaScript Object Signing and Encryption (JOSE) indicates that JWE is using JWE Compact Serialization scheme. Format: Value is JOSE. |
kid | (Optional) Key identifier that identifies the key used to encrypt the CEK, which is the Issuer’s API key. Format: String; max length 64 character |
enc | (Required) Type of encryption used by the CEK to encrypt sensitive payload elements. Format: Values are A128GCM and A256GCM. |
iat | (Optional) Time when JWE was issued. Expressed in UNIX epoch time (seconds since 1 January 1970) and issued at timestamp in UTC when the transaction was created and signed. Format: Epoch time in seconds |
exp | (Optional) Expiration time of the payload. This field is optional and will be evaluated in conjunction with the ttl default defined with use case (or product). Ttl (time to live) is a value for the period of time (in seconds) the message is valid for. exp can be used to reduce the default ONLY. If exp represents a time greater than iat + ttl then iat + ttl will be used. exp is calculated as iat + ttl Format: Epoch time in seconds |
iss | (Optional) Message originator client ID, which is the vClientID of the issuer. The field is required for pushing card enrollment to wallet providers. The message originator is the issuer. Format: String; alphanumeric; max length 64 characters. |
aud | (Optional) List of desired recipients, which are the token requestors’ vClientID values. This field is required for pushing card enrollment to wallet providers. The recipients are token requestors. The value should be a comma-separated array of client IDs. Up to 10 client IDs are allowed for each request. (Optional) Format: String; alphanumeric; max length 256 characters. |
channelSecurityContext | This indicates which channel security to use for encryption & decryption Values: RSA_PKI, RSA_PKI2, OPACITY_A, OPACITY_B, SHARED_SECRET |
jti |
(Optional) The "jti" (JWT ID) claim provides a unique identifier for the JWT. |
The JWE Initialization Vector (IV) is a randomly generated initialization vector (also known as salt) of 96 bits length in Base 64 URL Safe encoded form.
JWE Ciphertext is an encrypted BLOB that is generated from the plaintext (sensitive data that needs to be encrypted), by using the A256GCM encryption scheme specified in the enc header field.
An HMAC (hash-based message authentication code) encryption of 128 bits is generated from the plaintext authentication tag using the A256GCM algorithm (A256GCM).
The JSON Web Signature (JWS) is a compact signature format intended for space constrained environments such as HTTP Authorization headers and URI query parameters. The JWS signature mechanisms are independent of the type of content being signed, allowing arbitrary content to be signed. A related encryption capability is described in a separate JSON Web Encryption (JWE) [JWE] specification.
Please refer to https://tools.ietf.org/html/rfc7515 for more details.
JWS represents signed content using JSON data structures and base64url encoding. The representation consists of three parts:
JWS Header
JWS Payload
JWS Signature
The three parts are base64url-encoded for transmission, and typically represented as the concatenation of the encoded strings in that order, with the three strings being separated by period ('.') characters.
The JWS Header describes the signature method and parameters employed. The JWS Payload is the message content to be secured. The JWS Signature ensures the integrity of both the JWS Header and the JWS Payload.
Base64URL (UTF-8 (JWS Header)) || ‘.’ || Base64URL (JWS Payload) || ‘.’ || Base64URL (JWS Signature)
Base64 encoding & conventions that Visa follows:
Visa has chosen to suffix “..” to the Base-64 encode values, instead of the more popular == convention.
The JWS header contains the metadata for signing.
Name |
Description |
alg | (Required) A description of the algorithm that is used to sign the JWS payload Format: Value is PS256 (RSA PKI) or HS256 (Shared Secret). |
kid | (Required) The key identifier that identifies the key used to sign the JWS payload. Format: String; max length 64 characters. |
typ | (Required) The media type of the JWS. JOSE indicates that the JWS is using the JWS Compact Serialization scheme. Format: Value is JOSE. |
cty | (Optional) The content type of the JWS payload. Format: Value is JWE string / content. |
iat | (Optional) Time when JWE was issued. Expressed in UNIX epoch time (seconds since 1 January 1970) and issued at timestamp in UTC when the transaction was created and signed. Format: Epoch time in seconds |
exp | (Optional) Expiration time of the payload. This field is optional and will be evaluated in conjunction with the ttl default defined with use case (or product). Ttl (time to live) is a value for the period of time (in seconds) the message is valid for. exp can be used to reduce the default ONLY. If exp represents a time greater than iat + ttl then iat + ttl will be used. exp is calculated as iat + ttl Format: Epoch time in seconds |
The JWS payload is the payload being signed.
The JWS signature is generated to protect the integrity of both the JWS header and JWE payload.
The encryption key provided during onboarding is used to encrypt and decrypt payloads. JSON Web Encryption (JWE) content should be signed or encrypted using the shared secret that was provided to client at the time of onboarding.
Below are the symmetric encryption parameters:
Note:
The JWE Protected Header is input as the AAD (Additional Authenticated Data) parameter of the authenticated encryption (AES-GCM) of the “text to encrypt”. The general approach for JWE Encryption using API Key / Shared Secret are as follows:
The JWE content should be encrypted using the public encryption key generated by the client and provided (in a certificate in PEM format) to Visa during onboarding.
Below are the asymmetric encryption parameters:
The general approach for encrypting data using JWE and RSA PKI is as follows:
To create a signature by applying JWS on JWE:
ASCII (Base64URL (UTF8 (JWS Header)) || ‘.’ || Base64URL(JWS Payload))
Base64URL (UTF8 (JWS Header)) || ‘.’ || Base64URL (JWE) || ‘.’ || Base64URL (JWS Signature)
Visa provides sample code in various languages, such as C#, Go Lang, Node JS, and Java, for handling JSON Web Encryption (JWE) for encryption and JSON Web Signatures (JWS) for object signing. To access these code samples, create an account on the Visa Developer Portal, log in, and scroll past My Projects on your dashboard to the General Assets, which include code samples for download.