From 70992c9a462fcfd53eb9aba4b52c21d3ba7facf2 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Mon, 1 Dec 2025 15:05:20 +0530 Subject: [PATCH] Update the decryptresponse service --- src/services/decryptResponse.js | 99 +++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 41 deletions(-) diff --git a/src/services/decryptResponse.js b/src/services/decryptResponse.js index 52b8a93a..9f66214e 100644 --- a/src/services/decryptResponse.js +++ b/src/services/decryptResponse.js @@ -1,47 +1,64 @@ -// Helper to convert Base64 to ArrayBuffer -const base64ToArrayBuffer = (base64) => { - const binaryString = window.atob(base64); - const len = binaryString.length; - const bytes = new Uint8Array(len); - for (let i = 0; i < len; i++) { - bytes[i] = binaryString.charCodeAt(i); - } - return bytes.buffer; -}; +import CryptoJS from 'crypto-js'; -// Main Decryption Function -export const decryptResponse = async (encryptedBase64) => { - const keyBase64 = "h9J4kL2mN5pQ8rS1tV3wX6yZ0aB7cD9eF1gH3jK5mN6="; // Same key - - // 1. Parse Key - const keyBytes = base64ToArrayBuffer(keyBase64); - const key = await window.crypto.subtle.importKey( - "raw", - keyBytes, - { name: "AES-GCM" }, - false, - ["decrypt"] - ); +// The key from your C# Middleware +// In a real app, prefer storing this in process.env.REACT_APP_ENCRYPTION_KEY +const KEY_BASE64 = "h9J4kL2mN5pQ8rS1tV3wX6yZ0aB7cD9eF1gH3jK5mN6="; - // 2. Parse Encrypted Data - const encryptedBytes = new Uint8Array(base64ToArrayBuffer(encryptedBase64)); +/** + * 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); - // 3. Extract Parts (Nonce is first 12 bytes) - const nonce = encryptedBytes.slice(0, 12); - const ciphertextWithTag = encryptedBytes.slice(12); // Web Crypto expects Tag appended to Ciphertext + // 2. Parse the incoming Base64 string to a WordArray + const fullWordArray = CryptoJS.enc.Base64.parse(encryptedBase64Str); - // 4. Decrypt - try { - const decryptedBuffer = await window.crypto.subtle.decrypt( - { name: "AES-GCM", iv: nonce }, - key, - ciphertextWithTag - ); + // 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); - const decoded = new TextDecoder().decode(decryptedBuffer); - return JSON.parse(decoded); - } catch (e) { - console.error("Decryption failed:", e); - return null; - } + // 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; + } }; \ No newline at end of file