praitv / lib /crypto.js
itzraissc
oi
78c3e1e
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 };