cross-crypto-ts
Version:
Cifrado híbrido seguro con interoperabilidad entre lenguajes como Python, TypeScript y Rust, basado en AES-GCM (256 bits) y RSA-OAEP (4096 bits).
60 lines (59 loc) • 2.87 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.decryptHybrid = decryptHybrid;
// src/decrypt.ts
const node_forge_1 = __importDefault(require("node-forge"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const v8_1 = __importDefault(require("v8"));
function decryptHybrid(encrypted, privateKeyPem, outPath) {
try {
const privateKey = node_forge_1.default.pki.privateKeyFromPem(privateKeyPem);
const aesKey = privateKey.decrypt(node_forge_1.default.util.decode64(encrypted.encryptedKey), 'RSA-OAEP');
const nonce = node_forge_1.default.util.decode64(encrypted.nonce);
const tag = node_forge_1.default.util.decode64(encrypted.tag);
const decipher = node_forge_1.default.cipher.createDecipher('AES-GCM', aesKey);
decipher.start({
iv: node_forge_1.default.util.createBuffer(nonce),
tag: node_forge_1.default.util.createBuffer(tag)
});
if (encrypted.mode === 'stream') {
if (!encrypted.encryptedPath)
throw new Error('Path no encontrado en payload stream.');
const encData = fs_1.default.readFileSync(encrypted.encryptedPath).toString('binary');
decipher.update(node_forge_1.default.util.createBuffer(encData));
const success = decipher.finish();
if (!success)
throw new Error('Tag inválido');
const finalPath = outPath || encrypted.encryptedPath.replace('.enc', '_recuperado' + path_1.default.extname(encrypted.encryptedPath));
fs_1.default.writeFileSync(finalPath, Buffer.from(decipher.output.getBytes(), 'binary'));
return finalPath;
}
const encryptedDataBytes = node_forge_1.default.util.decode64(encrypted.encryptedData);
decipher.update(node_forge_1.default.util.createBuffer(encryptedDataBytes));
const success = decipher.finish();
if (!success)
throw new Error('Tag inválido');
if (encrypted.mode === 'json') {
const output = decipher.output.toString();
return JSON.parse(output);
}
else if (encrypted.mode === 'binary') {
return Buffer.from(decipher.output.getBytes(), 'binary');
}
else if (encrypted.mode === 'v8') {
const buffer = Buffer.from(decipher.output.getBytes(), 'binary');
return v8_1.default.deserialize(buffer);
}
else {
throw new Error(`Modo desconocido: ${encrypted.mode}`);
}
}
catch (e) {
console.error('❌ Error desencriptando:', e);
throw new Error('Desencriptación fallida');
}
}