HMAC Validation
Introduction
This is the code snippet that can be integrated into your system to validate the HMAC secret key while your end customers provide you consent for their Digilocker account. This is created as a step to avoid third parties in the middle of the data transmission. When hmacSecret is added, the end customer will get __hmac in their callback response which can be validated by you. The Signzy support team will provide you with an HMAC secret key, which you can validate when your end customer completes the Digilocker journey.
Code Snippet
const crypto = require("crypto");
/**
* Checks if the given object is primitive value or not (string, number or boolean)
* @param {any} variable Some object
* @returns {boolean}
*/
function isPrimitive(variable) {
return (
typeof variable === "string" ||
typeof variable === "number" ||
typeof variable === "boolean"
);
}
/**
* Flatten and sort a nested object into a flat object.
* @param {Object} obj - The object to flatten.
*/
function flattenAndSort(obj) {
const flatObject = {};
/**
* Recursive function to flatten the nested object.
* @param {Object} obj - The object to flatten.
* @param {string} [prefix=''] - The prefix for keys in the flattened object.
*/
function flatten(obj, prefix = "") {
if (isPrimitive(obj)) {
flatObject[prefix] = obj.toString();
return;
}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const newKey = prefix ? `${prefix}.${key}` : key;
if (obj[key] === null) {
flatObject[newKey] = "";
} else if (Array.isArray(obj[key])) {
obj[key].forEach((item, index) => {
flatten(item, `${newKey}.${index}`);
});
} else if (typeof obj[key] === "object") {
flatten(obj[key], newKey);
} else {
flatObject[newKey] = obj[key].toString();
}
}
}
}
flatten(obj);
// console.log(flatObject);
// Sort the keys
const sortedKeys = Object.keys(flatObject).sort();
// Create a string of values separated by a pipe (|)
const valuesString = sortedKeys.map((key) => flatObject[key]).join("|");
return valuesString;
}
/**
* Generate HMAC using SHA-256 algorithm.
* @param {string} data - The data to generate HMAC from.
* @param {string} secret - The secret key for HMAC generation.
* @returns {string} The generated HMAC.
*/
function generateHMAC(data, secret) {
const hmac = crypto.createHmac("sha256", secret);
hmac.update(data);
return hmac.digest("hex");
}
// console.log(flattenAndSort(require("./mockData.json")));
/**
* Returns true if the hmac is valid for data and secret
* @example
* verifyHmac(callbackData, callbackData.__hmac, "secret")
* @param {Object} data Data object sent in the callback
* @param {string} hmac Hmac string returned in the callback
* @param {string} secret Secret key
* @returns {boolean}
*/
function verifyHmac(data, hmac, secret) {
const deepCopyData = JSON.parse(JSON.stringify(data));
delete deepCopyData.__hmac;
console.log(deepCopyData);
let hmacString = flattenAndSort(deepCopyData);
console.log(hmacString);
const generatedHmac = generateHMAC(hmacString, secret);
console.log(generatedHmac);
return hmac === generatedHmac;
}
console.log(
verifyHmac(
require("./testData.json"),
"542d37908dc146f0e808b418014eaeb19f6c22179f7459166d5dd28a0946750c",
"5e6b4e2e778fc750b7fcdhmac"
)
);Contact Us for Any Assistance
If you have any questions or need assistance, please reach out to our customer support team. You can contact us via email at [email protected]. We strive to provide prompt and reliable assistance, ensuring your queries are addressed effectively.
We value your feedback and are committed to making your experience smooth and enjoyable. Our team is dedicated to assisting you with any needs you may have. Thank you for choosing our services. We look forward to helping you!