UNPKG

@midasr/novashadowcookie

Version:

Module NPM natif pour le décryptage des données Chrome App-Bound Encryption, compatible avec Node.js et Bun

271 lines (235 loc) 7.81 kB
// index.js - Point d'entrée principal du module chrome-decrypt-native 'use strict'; const path = require('path'); const fs = require('fs'); let nativeAddon; try { // Essayer de charger le module natif compilé nativeAddon = require('./build/Release/chrome_decrypt_native.node'); } catch (error) { try { // Fallback vers le build Debug nativeAddon = require('./build/Debug/chrome_decrypt_native.node'); } catch (debugError) { throw new Error( 'Could not load chrome-decrypt-native binary. ' + 'Make sure to run "npm run build" first.\n' + 'Release error: ' + error.message + '\n' + 'Debug error: ' + debugError.message ); } } /** * Décrypte les données d'un profil Chrome/Edge/Brave * @param {string} profilePath - Chemin vers le profil du navigateur * @param {string} outputPath - Dossier de sortie pour les données extraites * @returns {Promise<Object>} Résultats de l'extraction */ async function decryptChromeData(profilePath, outputPath) { if (typeof profilePath !== 'string') { throw new TypeError('profilePath must be a string'); } if (typeof outputPath !== 'string') { throw new TypeError('outputPath must be a string'); } return nativeAddon.decryptChromeData(profilePath, outputPath); } /** * Chiffre/déchiffre des données avec ChaCha20 * @param {Buffer} data - Données à traiter * @param {Buffer} key - Clé de 32 bytes * @param {Buffer} nonce - Nonce de 12 bytes * @returns {Buffer} Données traitées */ function chaCha20Encrypt(data, key, nonce) { if (!Buffer.isBuffer(data)) { throw new TypeError('data must be a Buffer'); } if (!Buffer.isBuffer(key)) { throw new TypeError('key must be a Buffer'); } if (!Buffer.isBuffer(nonce)) { throw new TypeError('nonce must be a Buffer'); } if (key.length !== 32) { throw new Error('key must be exactly 32 bytes'); } if (nonce.length !== 12) { throw new Error('nonce must be exactly 12 bytes'); } return nativeAddon.chaCha20Encrypt(data, key, nonce); } /** * Extrait la clé maître chiffrée du fichier Local State * @param {string} localStatePath - Chemin vers le fichier Local State * @returns {Buffer} Clé chiffrée */ function getEncryptedMasterKey(localStatePath) { if (typeof localStatePath !== 'string') { throw new TypeError('localStatePath must be a string'); } if (!fs.existsSync(localStatePath)) { throw new Error('Local State file not found: ' + localStatePath); } return nativeAddon.getEncryptedMasterKey(localStatePath); } /** * Décrypte des données AES-GCM * @param {Buffer} key - Clé de déchiffrement * @param {Buffer} encryptedData - Données chiffrées avec préfixe v20 * @returns {Buffer|null} Données déchiffrées ou null si échec */ function decryptGCM(key, encryptedData) { if (!Buffer.isBuffer(key)) { throw new TypeError('key must be a Buffer'); } if (!Buffer.isBuffer(encryptedData)) { throw new TypeError('encryptedData must be a Buffer'); } return nativeAddon.decryptGCM(key, encryptedData); } /** * Trouve automatiquement les profils Chrome/Edge/Brave * @returns {string[]} Tableau des chemins vers les profils trouvés */ function findChromeProfiles() { return nativeAddon.findChromeProfiles(); } /** * Trouve automatiquement les profils avec informations détaillées * @returns {Object[]} Tableau d'informations sur les profils trouvés */ function findChromeProfilesDetailed() { const profiles = findChromeProfiles(); return profiles.map(profilePath => { const parts = profilePath.split(path.sep); let browser = 'Unknown'; let profileName = 'Default'; // Déterminer le navigateur if (profilePath.includes('Google\\Chrome')) { browser = 'Chrome'; } else if (profilePath.includes('Microsoft\\Edge')) { browser = 'Edge'; } else if (profilePath.includes('BraveSoftware\\Brave-Browser')) { browser = 'Brave'; } // Déterminer le nom du profil const lastPart = parts[parts.length - 1]; if (lastPart !== 'Default') { profileName = lastPart; } // Construire le chemin Local State const userDataPath = path.dirname(profilePath); const localStatePath = path.join(userDataPath, 'Local State'); return { browser, profileName, profilePath, localStatePath }; }); } /** * Convertit un Buffer en string hexadécimale * @param {Buffer} buffer - Buffer à convertir * @returns {string} String hexadécimale */ function bufferToHex(buffer) { if (!Buffer.isBuffer(buffer)) { throw new TypeError('buffer must be a Buffer'); } return nativeAddon.bufferToHex(buffer); } /** * Convertit une string hexadécimale en Buffer * @param {string} hex - String hexadécimale * @returns {Buffer} Buffer correspondant */ function hexToBuffer(hex) { if (typeof hex !== 'string') { throw new TypeError('hex must be a string'); } if (!/^[0-9a-fA-F]*$/.test(hex)) { throw new Error('hex must contain only hexadecimal characters'); } if (hex.length % 2 !== 0) { throw new Error('hex string must have even length'); } return nativeAddon.hexToBuffer(hex); } /** * Valide qu'un chemin est un profil Chrome valide * @param {string} profilePath - Chemin à valider * @returns {boolean} true si le profil est valide */ function isValidChromeProfile(profilePath) { if (typeof profilePath !== 'string') { return false; } return nativeAddon.isValidChromeProfile(profilePath); } /** * Obtient des informations sur un profil spécifique * @param {string} profilePath - Chemin vers le profil * @returns {Object|null} Informations sur le profil ou null si invalide */ function getProfileInfo(profilePath) { if (!isValidChromeProfile(profilePath)) { return null; } const detailed = findChromeProfilesDetailed(); return detailed.find(profile => profile.profilePath === profilePath) || null; } /** * Génère une clé aléatoire * @param {number} [size=32] - Taille de la clé en bytes * @returns {Buffer} Buffer contenant la clé générée */ function generateKey(size = 32) { if (typeof size !== 'number' || size <= 0) { throw new TypeError('size must be a positive number'); } return nativeAddon.generateKey(size); } /** * Génère un nonce aléatoire * @param {number} [size=12] - Taille du nonce en bytes * @returns {Buffer} Buffer contenant le nonce généré */ function generateNonce(size = 12) { if (typeof size !== 'number' || size <= 0) { throw new TypeError('size must be a positive number'); } return nativeAddon.generateNonce(size); } // Alias pour compatibilité const encrypt = chaCha20Encrypt; const decrypt = decryptChromeData; // Métadonnées du module const version = nativeAddon.version; const supportedBrowsers = nativeAddon.supportedBrowsers; // Exports CommonJS module.exports = { // Fonctions principales decryptChromeData, chaCha20Encrypt, getEncryptedMasterKey, decryptGCM, findChromeProfiles, findChromeProfilesDetailed, // Utilitaires bufferToHex, hexToBuffer, isValidChromeProfile, getProfileInfo, generateKey, generateNonce, // Alias encrypt, decrypt, // Métadonnées version, supportedBrowsers }; // Support ESM (export named et default) module.exports.default = module.exports;