marco.pms.web/src/services/decryptResponse.js

64 lines
2.2 KiB
JavaScript

import CryptoJS from 'crypto-js';
// The key from your C# Middleware
// In a real app, prefer storing this in process.env.REACT_APP_ENCRYPTION_KEY
// const KEY_BASE64 = "h9J4kL2mN5pQ8rS1tV3wX6yZ0aB7cD9eF1gH3jK5mN6=";
const KEY_BASE64 = "u4J7p9Qx2hF5vYtLz8Kq3mN1sG0bRwXyZcD6eH8jFQw=";
/**
* Decrypts the specific format sent by the C# EncryptionMiddleware.
* Format: Base64([IV (16 bytes)] + [Encrypted Data])
* * @param {string} encryptedBase64Str - The raw response text from the API
* @returns {any} - The parsed JSON object or string
*/
export const decryptResponse = (encryptedBase64Str) => {
try {
// 1. Parse the Key
const key = CryptoJS.enc.Base64.parse(KEY_BASE64);
// 2. Parse the incoming Base64 string to a WordArray
const fullWordArray = CryptoJS.enc.Base64.parse(encryptedBase64Str);
// 3. Convert to Hex to easily slice the IV (16 bytes = 32 hex chars)
// This is safer than manipulating WordArray indices directly
const fullHex = CryptoJS.enc.Hex.stringify(fullWordArray);
// 4. Extract IV (First 16 bytes / 32 hex characters)
const ivHex = fullHex.substring(0, 32);
const iv = CryptoJS.enc.Hex.parse(ivHex);
// 5. Extract Ciphertext (The rest of the string)
const cipherTextHex = fullHex.substring(32);
const cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Hex.parse(cipherTextHex)
});
// 6. Decrypt
const decrypted = CryptoJS.AES.decrypt(
cipherParams,
key,
{
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
// 7. Convert to UTF-8 String
const decryptedString = decrypted.toString(CryptoJS.enc.Utf8);
if (!decryptedString) {
throw new Error("Decryption produced empty result (Wrong Key/IV?)");
}
// 8. Try to parse JSON, otherwise return plain string
try {
return JSON.parse(decryptedString);
} catch {
return decryptedString;
}
} catch (error) {
console.error("Decryption Failed:", error);
return null;
}
};