const crypto = require('crypto'); /** * AES-256-CBC encryption compatible with OpenSSL legacy format (Salted__ prefix, MD5 key derivation) * Used by the APK middleware for encrypting/decrypting authentication data. */ /** * EVP_BytesToKey with MD5 — replicates OpenSSL's legacy key derivation */ function deriveKeyAndIv(password, salt) { const passwordBuf = Buffer.from(password, 'utf8'); let key = Buffer.alloc(0); let iv = Buffer.alloc(0); let lastHash = Buffer.alloc(0); while (key.length + iv.length < 48) { const hash = crypto.createHash('md5'); hash.update(lastHash); hash.update(passwordBuf); hash.update(salt); lastHash = hash.digest(); let remaining = lastHash; if (key.length < 32) { const keyToCopy = Math.min(32 - key.length, remaining.length); key = Buffer.concat([key, remaining.slice(0, keyToCopy)]); remaining = remaining.slice(keyToCopy); } if (remaining.length > 0 && iv.length < 16) { const ivToCopy = Math.min(16 - iv.length, remaining.length); iv = Buffer.concat([iv, remaining.slice(0, ivToCopy)]); } } return { key, iv }; } function encrypt(text, password) { const salt = crypto.randomBytes(8); const keyIv = deriveKeyAndIv(password, salt); const cipher = crypto.createCipheriv('aes-256-cbc', keyIv.key, keyIv.iv); let encrypted = cipher.update(text, 'utf8'); encrypted = Buffer.concat([encrypted, cipher.final()]); const prefix = Buffer.from('Salted__'); const result = Buffer.concat([prefix, salt, encrypted]); return result.toString('base64'); } function decrypt(ciphertext, password) { const buffer = Buffer.from(ciphertext, 'base64'); if (buffer.slice(0, 8).toString('utf8') !== 'Salted__') { throw new Error('Invalid encryption prefix (expected Salted__)'); } const salt = buffer.slice(8, 16); const encryptedData = buffer.slice(16); const keyIv = deriveKeyAndIv(password, salt); const decipher = crypto.createDecipheriv('aes-256-cbc', keyIv.key, keyIv.iv); let decrypted = decipher.update(encryptedData); decrypted = Buffer.concat([decrypted, decipher.final()]); return decrypted.toString('utf8'); } module.exports = { encrypt, decrypt, deriveKeyAndIv };