import * as crypto from "crypto";
import * as fs from "fs";
const PRIVATE_KEY = fs.readFileSync(`path/to/your/private-key.pem`, "utf8");
const AES_KEY_LENGTH = 32; // 256 bits
const IV_LENGTH = 12; // 96 bits
const AUTH_TAG_LENGTH = 16; // 128 bits
function hybridDecrypt(cardEncryptedData) {
const { encryptedData, encryptedKey } = cardEncryptedData;
try {
// 1. RSA Decryption
const decryptedKeyBuf = crypto.privateDecrypt(
{
key: PRIVATE_KEY,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256"
},
encryptedKey
);
// 2. Extract AES Parameters
const aesKey = decryptedKeyBuf.subarray(0, AES_KEY_LENGTH);
const iv = decryptedKeyBuf.subarray(AES_KEY_LENGTH, AES_KEY_LENGTH + IV_LENGTH);
const authTag = decryptedKeyBuf.subarray(-AUTH_TAG_LENGTH);
// 3. AES-GCM Decryption
const decipher = crypto.createDecipheriv("aes-256-gcm", aesKey, iv);
decipher.setAuthTag(authTag);
let decrypted = decipher.update(encryptedData, "base64", "utf8");
decrypted += decipher.final("utf8");
return decrypted;
} catch (error) {
console.log(`call to hybridDecrypt failed with error: ${error.message}`);
return "{}";
}
}
// Test with NeoX virtual card encrypted data. Replace with actual encrypted data
const cardEncryptedData = {
encryptedData:
"Some encryptedData data here that is base64 encoded",
encryptedKey:
"Some encryptedKey data here that is base64 encoded"
};
const result = hybridDecrypt(cardEncryptedData);
console.log("result", JSON.parse(result));