import { ipcMain } from 'electron'; import * as crypto from 'crypto'; import * as fs from 'fs'; import * as path from 'path'; import os from 'os'; ipcMain.handle('decrypt', async (event, { encryptedData, userId }) => { try { if (!userId) throw 'User ID not provided'; // Determine base directory based on OS let baseDir; if (process.platform === 'win32') { baseDir = path.join(os.homedir(), 'AppData', 'Roaming', 'ultima'); } else if (process.platform === 'linux') { baseDir = path.join(os.homedir(), '.ultima'); } else if (process.platform === 'darwin') { baseDir = path.join(os.homedir(), 'Library', 'Application Support', 'Ultima'); } // Define file paths const userDir = path.join(baseDir, 'Sessions', userId); const epkFilePath = path.join(userDir, 'epk.txt'); const passphraseFilePath = path.join(userDir, 'passphrase.txt'); // Check if files exist if (!fs.existsSync(epkFilePath) || !fs.existsSync(passphraseFilePath)) { throw 'Keys or passphrase not found'; } // Read epk and passphrase from files const epk = fs.readFileSync(epkFilePath, 'utf8'); const passphrase = fs.readFileSync(passphraseFilePath, 'utf8').trim(); // Extract IV and encrypted private key const [ivHex, encryptedPrivateKey] = epk.split(':'); const iv = Buffer.from(ivHex, 'hex'); // Pad passphrase to 32 bytes const paddedPassphrase = Buffer.from(passphrase.padEnd(32, ' ')); // Decrypt the private key using the padded passphrase and IV const decipher = crypto.createDecipheriv('aes-256-cbc', paddedPassphrase, iv); let decryptedPrivateKey = decipher.update(encryptedPrivateKey, 'hex', 'utf8'); decryptedPrivateKey += decipher.final('utf8'); // Decrypt the provided object using the decrypted private key const [encryptedAesKeyHex, dataIvHex, encryptedDataHex] = encryptedData.split(':'); const dataIv = Buffer.from(dataIvHex, 'hex'); const encryptedAesKey = Buffer.from(encryptedAesKeyHex, 'hex'); // Decrypt AES key with RSA private key const aesKey = crypto.privateDecrypt( { key: decryptedPrivateKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: 'sha256' }, encryptedAesKey ); // Decrypt data with AES key const decipherData = crypto.createDecipheriv('aes-256-cbc', aesKey, dataIv); let decryptedData = decipherData.update(encryptedDataHex, 'hex', 'utf8'); decryptedData += decipherData.final('utf8'); // Parse JSON if the decrypted data is an object try { decryptedData = JSON.parse(decryptedData); } catch (e) { // Not a JSON object, return as string } return decryptedData; } catch (error) { throw error; } });