NodeJS library for Mastercard API compliant payload encryption/decryption.
- NodeJS 6.12.3+
- NodeJS 13.14.0+ (JWE features)
There shouldn't be any Node compatibility issues with this package, but it's a good idea to keep your Node versions up-to-date. It is recommended that you use one of the LTS Node.js releases, or one of the more general recent releases. A Node version manager such as nvm (Mac and Linux) or nvm-windows is a good way to stay on top of this.
Before using this library, you will need to set up a project in the Mastercard Developers Portal.
As part of this set up, you'll receive:
- A public request encryption certificate (aka Client Encryption Keys)
- A private response decryption key (aka Mastercard Encryption Keys)
If you want to use mastercard-client-encryption with Node.js, it is available through npm:
Adding the library to your project:
npm install mastercard-client-encryptionYou can then use it as a regular module:
constclientEncryption=require("mastercard-client-encryption");The core methods responsible for payload encryption and decryption are encryptData and decryptData in the FieldLevelEncryption class.
encrypt()usage:
constfle=newclientEncryption.FieldLevelEncryption(config);// …letencryptedRequestPayload=fle.encrypt(endpoint,header,body);decrypt()usage:
constfle=newclientEncryption.FieldLevelEncryption(config);// …letresponsePayload=fle.decrypt(encryptedResponsePayload);FieldLevelEncryption needs a config object to instruct how to decrypt/decrypt the payloads. Example:
constconfig={paths: [{path: "/resource",toEncrypt: [{/* path to element to be encrypted in request json body */element: "path.to.foo",/* path to object where to store encryption fields in request json body */obj: "path.to.encryptedFoo",},],toDecrypt: [{/* path to element where to store decrypted fields in response object */element: "path.to.encryptedFoo",/* path to object with encryption fields */obj: "path.to.foo",},],},],ivFieldName: "iv",encryptedKeyFieldName: "encryptedKey",encryptedValueFieldName: "encryptedData",dataEncoding: "hex",encryptionCertificate: "./path/to/public.cert",privateKey: "./path/to/your/private.key",oaepPaddingDigestAlgorithm: "SHA-256",};For all config options, please see:
- Configuration object for all config options
We have a predefined set of configurations to use with Mastercard services:
Call FieldLevelEncryption.encrypt() with a JSON request payload, and optional header object.
Example using the configuration above:
constpayload={path: {to: {foo: {sensitive: "this is a secret!",sensitive2: "this is a super-secret!",},},},};constfle=new(require("mastercard-client-encryption").FieldLevelEncryption)(config);// …letresponsePayload=fle.encrypt("/resource1",header,payload);Output:
{
"path": {
"to": {
"encryptedFoo": {
"iv": "7f1105fb0c684864a189fb3709ce3d28",
"encryptedKey": "67f467d1b653d98411a0c6d3c…ffd4c09dd42f713a51bff2b48f937c8",
"encryptedData": "b73aabd267517fc09ed72455c2…dffb5fa04bf6e6ce9ade1ff514ed6141",
"publicKeyFingerprint": "80810fc13a8319fcf0e2e…82cc3ce671176343cfe8160c2279",
"oaepHashingAlgorithm": "SHA256"
}
}
}
}Call FieldLevelEncryption.decrypt() with an (encrypted) response object with the following fields:
body: json payloadrequest.url: requesting urlheader: optional, header object
Example using the configuration above:
constresponse={};response.request={url: "/resource1"};response.body={path: {to: {encryptedFoo: {iv: "e5d313c056c411170bf07ac82ede78c9",encryptedKey:
"e3a56746c0f9109d18b3a2652b76…f16d8afeff36b2479652f5c24ae7bd",encryptedData:
"809a09d78257af5379df0c454dcdf…353ed59fe72fd4a7735c69da4080e74f",oaepHashingAlgorithm: "SHA256",publicKeyFingerprint: "80810fc13a8319fcf0e2e…3ce671176343cfe8160c2279",},},},};constfle=new(require("mastercard-client-encryption").FieldLevelEncryption)(config);letresponsePayload=fle.decrypt(response);Output:
{
"path": {
"to": {
"foo": {
"sensitive": "this is a secret",
"sensitive2": "this is a super secret!"
}
}
}
}- Introduction
- Configuring the JWE Encryption
- Performing JWE Encryption
- Performing JWE Decryption
- Encrypting Entire Payloads
- Decrypting Entire Payloads
This library uses JWE compact serialization for the encryption of sensitive data.
The core methods responsible for payload encryption and decryption are encryptData and decryptData in the JweEncryption class.
encryptPayloadusage:
constjwe=newclientEncryption.JweEncryption(config);// …letencryptedRequestPayload=jwe.encrypt(endpoint,header,body);decryptPayloadusage:
constjwe=newclientEncryption.JweEncryption(config);// …letresponsePayload=jwe.decrypt(encryptedResponsePayload);JweEncryption needs a config object to instruct how to decrypt/decrypt the payloads. Example:
constconfig={paths: [{path: "/resource1",toEncrypt: [{/* path to element to be encrypted in request json body */element: "path.to.foo",/* path to object where to store encryption fields in request json body */obj: "path.to.encryptedFoo",},],toDecrypt: [{/* path to element where to store decrypted fields in response object */element: "path.to.encryptedFoo",/* path to object with encryption fields */obj: "path.to.foo",},],},],mode: "JWE",encryptedValueFieldName: "encryptedData",encryptionCertificate: "./path/to/public.cert",privateKey: "./path/to/your/private.key",};Mode must be set to JWE to use JWE encryption
Call JweEncryption.encrypt() with a JSON request payload, and optional header object.
Example using the configuration above:
constpayload={path: {to: {foo: {sensitive: "this is a secret!",sensitive2: "this is a super-secret!",},},},};constjwe=new(require("mastercard-client-encryption").JweEncryption)(config);// …letresponsePayload=jwe.encrypt("/resource1",header,payload);Output:
{
"path": {
"to": {
"encryptedFoo": {
"encryptedData": "eyJraWQiOiI3NjFiMDAzYzFlYWRlM….Y+oPYKZEMTKyYcSIVEgtQw"
}
}
}
}Call JweEncryption.decrypt() with an (encrypted) response object with the following fields:
Example using the configuration above:
constresponse={};response.request={url: "/resource1"};response.body="{"+' "path": {'+' "to": {'+' "encryptedFoo": {'+' "encryptedData": "eyJraWQiOiI3NjFiMDAzYzFlYWRlM….Y+oPYKZEMTKyYcSIVEgtQw"'+" }"+" }"+" }"+"}";constjwe=new(require("mastercard-client-encryption").JweEncryption)(config);letresponsePayload=jwe.decrypt(response);Output:
{
"path": {
"to": {
"foo": {
"sensitive": "this is a secret",
"sensitive2": "this is a super secret!"
}
}
}
}Entire payloads can be encrypted using the "$" operator as encryption path:
constconfig={paths: [{path: "/resource1",toEncrypt: [{/* path to element to be encrypted in request json body */element: "$",/* path to object where to store encryption fields in request json body */obj: "$",},],toDecrypt: [],},],mode: "JWE",encryptedValueFieldName: "encryptedData",encryptionCertificate: "./path/to/public.cert",privateKey: "./path/to/your/private.key",};Example:
constpayload="{"+' "sensitive": "this is a secret",'+' "sensitive2": "this is a super secret!"'+"}";constjwe=new(require("mastercard-client-encryption").JweEncryption)(config);// …letresponsePayload=jwe.encrypt("/resource1",header,payload);Output:
{
"encryptedData": "eyJraWQiOiI3NjFiMDAzYzFlYWRlM….Y+oPYKZEMTKyYcSIVEgtQw"
}Entire payloads can be decrypted using the "$" operator as decryption path:
constconfig={paths: [{path: "/resource1",toEncrypt: [],toDecrypt: [{/* path to element where to store decrypted fields in response object */element: "$",/* path to object with encryption fields */obj: "$",},],},],mode: "JWE",encryptedValueFieldName: "encryptedData",encryptionCertificate: "./path/to/public.cert",privateKey: "./path/to/your/private.key",};Example:
constencryptedPayload="{"+' "encryptedData": "eyJraWQiOiI3NjFiMDAzYzFlYWRlM….Y+oPYKZEMTKyYcSIVEgtQw"'+"}";constjwe=new(require("mastercard-client-encryption").JweEncryption)(config);letresponsePayload=jwe.decrypt(encryptedPayload);Output:
{
"sensitive": "this is a secret",
"sensitive2": "this is a super secret!"
}OpenAPI Generator generates API client libraries from OpenAPI Specs. It provides generators and library templates for supporting multiple languages and frameworks.
The client-encryption-nodejs library provides the Service decorator object you can use with the OpenAPI generated client. This class will take care of encrypting request and decrypting response payloads, but also of updating HTTP headers when needed, automatically, without manually calling encrypt()/decrypt() functions for each API request or response.
OpenAPI client can be generated, starting from your OpenAPI Spec / Swagger using the following command:
openapi-generator-cli generate -i openapi-spec.yaml -l javascript -o outClient library will be generated in the out folder.
See also:
To use it:
Generate the OpenAPI client, as above
Import the mastercard-client-encryption library
constmcapi=require("mastercard-client-encryption");
Import the OpenAPI Client using the
Servicedecorator object:constopenAPIClient=require("./path/to/generated/openapi/client");constconfig={/* service configuration object */};constservice=newmcapi.Service(openAPIClient,config);
Use the
serviceobject as you are using theopenAPIClientto make API requests.Example:
letapi=service.ServiceApi();letmerchant=/* … */api.createMerchants(merchant,(error,data,response)=>{// requests and responses will be automatically encrypted and decrypted// accordingly with the configuration used to instantiate the mcapi.Service./* use response/data object here */});
