UNPKG

bigbasealpha

Version:

Enterprise-Grade NoSQL Database System with Modular Logger & Offline HSM Security - Complete database platform with professional text-based logging, encryption, caching, indexing, JWT authentication, auto-generated REST API, real-time dashboard, and maste

575 lines (477 loc) 18.7 kB
/** * BigBaseAlpha HSM (Hardware Security Module) - Offline Implementation * 100% Offline, Self-Contained Hardware Security Module * * @author ByAlphas * @version 1.5.0 * @copyright 2025 ByAlphas. All rights reserved. */ import crypto from 'crypto'; import fs from 'fs'; import path from 'path'; import os from 'os'; import { EventEmitter } from 'events'; /** * Offline HSM Implementation for BigBaseAlpha * Provides hardware-level security simulation with software-based protection */ class OfflineHSM extends EventEmitter { constructor(options = {}) { super(); // Logger support for v1.5.1 this.logger = options.logger || { success: (msg) => console.log(`[SUCCESS] [HSM] ${msg}`), info: (msg) => console.log(`[INFO] [HSM] ${msg}`), warn: (msg) => console.log(`[WARN] [HSM] ${msg}`), error: (msg) => console.log(`[ERROR] [HSM] ${msg}`), process: (msg) => console.log(`[PROCESS] [HSM] ${msg}`) }; this.config = { keySize: options.keySize || 256, algorithm: options.algorithm || 'aes-256-gcm', iterations: options.iterations || 100000, saltSize: options.saltSize || 32, ivSize: options.ivSize || 16, tagSize: options.tagSize || 16, secureStorePath: options.secureStorePath || './bigbase_data/hsm', tamperDetection: options.tamperDetection !== false, autoBackup: options.autoBackup !== false, maxKeyAge: options.maxKeyAge || 7776000000, // 90 days in ms ...options }; this.keyStore = new Map(); this.accessLog = []; this.tamperFlags = new Set(); this.isInitialized = false; this.lastHealthCheck = null; this._initializeSecureStorage(); } /** * Initialize HSM secure storage */ async _initializeSecureStorage() { try { // Create secure storage directory if (!fs.existsSync(this.config.secureStorePath)) { fs.mkdirSync(this.config.secureStorePath, { recursive: true, mode: 0o700 // Restricted permissions }); } // Initialize tamper detection if (this.config.tamperDetection) { await this._initializeTamperDetection(); } // Load existing keys await this._loadKeyStore(); this.isInitialized = true; this.emit('hsm:initialized'); this.logger.success('BigBaseAlpha HSM initialized successfully (Offline Mode)'); } catch (error) { this.emit('hsm:error', error); throw new Error(`HSM initialization failed: ${error.message}`); } } /** * Initialize tamper detection system */ async _initializeTamperDetection() { const tamperFile = path.join(this.config.secureStorePath, '.tamper'); const systemFingerprint = this._generateSystemFingerprint(); if (fs.existsSync(tamperFile)) { const storedFingerprint = fs.readFileSync(tamperFile, 'utf8'); if (storedFingerprint !== systemFingerprint) { this.tamperFlags.add('system_modified'); this.emit('hsm:tamper_detected', 'System fingerprint mismatch'); } } else { fs.writeFileSync(tamperFile, systemFingerprint, { mode: 0o600 }); } } /** * Generate system fingerprint for tamper detection */ _generateSystemFingerprint() { const fingerprint = { platform: os.platform(), arch: os.arch(), hostname: os.hostname(), cpus: os.cpus().length, totalmem: os.totalmem(), process_pid: process.pid }; return crypto.createHash('sha256') .update(JSON.stringify(fingerprint)) .digest('hex'); } /** * Generate a new cryptographic key */ async generateKey(keyId, keyType = 'symmetric', keySize = null) { this._validateInitialized(); this._logAccess('generateKey', keyId); const actualKeySize = keySize || this.config.keySize; let keyData; switch (keyType) { case 'symmetric': keyData = crypto.randomBytes(actualKeySize / 8); break; case 'asymmetric': const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: actualKeySize * 8, publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); keyData = { publicKey, privateKey }; break; case 'ecdsa': const ecKeyPair = crypto.generateKeyPairSync('ec', { namedCurve: 'secp256k1', publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); keyData = { publicKey: ecKeyPair.publicKey, privateKey: ecKeyPair.privateKey }; break; default: throw new Error(`Unsupported key type: ${keyType}`); } const keyEntry = { id: keyId, type: keyType, size: actualKeySize, data: keyData, created: Date.now(), lastUsed: Date.now(), usageCount: 0, metadata: { algorithm: this.config.algorithm, version: '1.5.0' } }; // Encrypt and store key await this._storeKey(keyId, keyEntry); this.keyStore.set(keyId, keyEntry); this.emit('hsm:key_generated', { keyId, keyType, size: actualKeySize }); return keyId; } /** * Encrypt data using HSM */ async encrypt(data, keyId, algorithm = null) { this._validateInitialized(); this._logAccess('encrypt', keyId); const keyEntry = this.keyStore.get(keyId); if (!keyEntry) { throw new Error(`Key not found: ${keyId}`); } const useAlgorithm = algorithm || this.config.algorithm; const iv = crypto.randomBytes(this.config.ivSize); let encrypted; if (keyEntry.type === 'symmetric') { const cipher = crypto.createCipher(useAlgorithm, keyEntry.data); cipher.setAutoPadding(true); encrypted = Buffer.concat([ cipher.update(Buffer.isBuffer(data) ? data : Buffer.from(data)), cipher.final() ]); // For GCM mode, include auth tag if (useAlgorithm.includes('gcm')) { const tag = cipher.getAuthTag(); encrypted = Buffer.concat([encrypted, tag]); } } else if (keyEntry.type === 'asymmetric') { encrypted = crypto.publicEncrypt(keyEntry.data.publicKey, Buffer.isBuffer(data) ? data : Buffer.from(data)); } else { throw new Error(`Encryption not supported for key type: ${keyEntry.type}`); } // Update key usage keyEntry.lastUsed = Date.now(); keyEntry.usageCount++; this.emit('hsm:data_encrypted', { keyId, size: encrypted.length }); return { encrypted: encrypted.toString('base64'), iv: iv.toString('base64'), algorithm: useAlgorithm, keyId: keyId }; } /** * Decrypt data using HSM */ async decrypt(encryptedData, keyId, algorithm = null) { this._validateInitialized(); this._logAccess('decrypt', keyId); const keyEntry = this.keyStore.get(keyId); if (!keyEntry) { throw new Error(`Key not found: ${keyId}`); } const useAlgorithm = algorithm || this.config.algorithm; const encrypted = Buffer.from(encryptedData.encrypted, 'base64'); let decrypted; if (keyEntry.type === 'symmetric') { const decipher = crypto.createDecipher(useAlgorithm, keyEntry.data); let encryptedBuffer = encrypted; // For GCM mode, extract auth tag if (useAlgorithm.includes('gcm')) { const tag = encryptedBuffer.slice(-this.config.tagSize); encryptedBuffer = encryptedBuffer.slice(0, -this.config.tagSize); decipher.setAuthTag(tag); } decrypted = Buffer.concat([ decipher.update(encryptedBuffer), decipher.final() ]); } else if (keyEntry.type === 'asymmetric') { decrypted = crypto.privateDecrypt(keyEntry.data.privateKey, encrypted); } else { throw new Error(`Decryption not supported for key type: ${keyEntry.type}`); } // Update key usage keyEntry.lastUsed = Date.now(); keyEntry.usageCount++; this.emit('hsm:data_decrypted', { keyId, size: decrypted.length }); return decrypted; } /** * Sign data using HSM */ async sign(data, keyId, algorithm = 'sha256') { this._validateInitialized(); this._logAccess('sign', keyId); const keyEntry = this.keyStore.get(keyId); if (!keyEntry) { throw new Error(`Key not found: ${keyId}`); } if (keyEntry.type !== 'asymmetric' && keyEntry.type !== 'ecdsa') { throw new Error(`Signing not supported for key type: ${keyEntry.type}`); } const signature = crypto.sign(algorithm, Buffer.from(data), keyEntry.data.privateKey); // Update key usage keyEntry.lastUsed = Date.now(); keyEntry.usageCount++; this.emit('hsm:data_signed', { keyId, algorithm }); return signature.toString('base64'); } /** * Verify signature using HSM */ async verify(data, signature, keyId, algorithm = 'sha256') { this._validateInitialized(); this._logAccess('verify', keyId); const keyEntry = this.keyStore.get(keyId); if (!keyEntry) { throw new Error(`Key not found: ${keyId}`); } if (keyEntry.type !== 'asymmetric' && keyEntry.type !== 'ecdsa') { throw new Error(`Verification not supported for key type: ${keyEntry.type}`); } const isValid = crypto.verify( algorithm, Buffer.from(data), keyEntry.data.publicKey, Buffer.from(signature, 'base64') ); // Update key usage keyEntry.lastUsed = Date.now(); keyEntry.usageCount++; this.emit('hsm:signature_verified', { keyId, algorithm, isValid }); return isValid; } /** * Generate secure hash */ async hash(data, algorithm = 'sha256', salt = null) { this._validateInitialized(); this._logAccess('hash', 'system'); const useSalt = salt || crypto.randomBytes(this.config.saltSize); const hash = crypto.createHash(algorithm); hash.update(useSalt); hash.update(Buffer.isBuffer(data) ? data : Buffer.from(data)); const result = hash.digest('hex'); this.emit('hsm:data_hashed', { algorithm, saltLength: useSalt.length }); return { hash: result, salt: useSalt.toString('hex'), algorithm: algorithm }; } /** * Perform HSM health check */ async healthCheck() { const health = { initialized: this.isInitialized, keysCount: this.keyStore.size, tamperFlags: Array.from(this.tamperFlags), lastCheck: this.lastHealthCheck, uptime: process.uptime(), memoryUsage: process.memoryUsage(), systemFingerprint: this._generateSystemFingerprint(), status: 'healthy' }; // Check for issues if (this.tamperFlags.size > 0) { health.status = 'compromised'; } else if (!this.isInitialized) { health.status = 'uninitialized'; } this.lastHealthCheck = Date.now(); this.emit('hsm:health_check', health); return health; } /** * Store encrypted key to disk */ async _storeKey(keyId, keyEntry) { const keyFile = path.join(this.config.secureStorePath, `${keyId}.hsmkey`); const masterKey = this._deriveMasterKey(); // Encrypt key data const iv = crypto.randomBytes(this.config.ivSize); const cipher = crypto.createCipherGCM(this.config.algorithm, masterKey, iv); const encrypted = Buffer.concat([ cipher.update(JSON.stringify(keyEntry)), cipher.final() ]); const tag = cipher.getAuthTag(); const keyFileData = { iv: iv.toString('base64'), tag: tag.toString('base64'), encrypted: encrypted.toString('base64'), created: Date.now() }; fs.writeFileSync(keyFile, JSON.stringify(keyFileData), { mode: 0o600 }); if (this.config.autoBackup) { await this._backupKey(keyId, keyFileData); } } /** * Load key store from disk */ async _loadKeyStore() { const files = fs.readdirSync(this.config.secureStorePath) .filter(file => file.endsWith('.hsmkey')); for (const file of files) { try { const keyId = path.basename(file, '.hsmkey'); const keyEntry = await this._loadKey(keyId); this.keyStore.set(keyId, keyEntry); } catch (error) { console.warn(`Failed to load key ${file}: ${error.message}`); } } } /** * Load and decrypt key from disk */ async _loadKey(keyId) { const keyFile = path.join(this.config.secureStorePath, `${keyId}.hsmkey`); if (!fs.existsSync(keyFile)) { throw new Error(`Key file not found: ${keyId}`); } const keyFileData = JSON.parse(fs.readFileSync(keyFile, 'utf8')); const masterKey = this._deriveMasterKey(); const iv = Buffer.from(keyFileData.iv, 'base64'); const tag = Buffer.from(keyFileData.tag, 'base64'); const encrypted = Buffer.from(keyFileData.encrypted, 'base64'); const decipher = crypto.createDecipherGCM(this.config.algorithm, masterKey, iv); decipher.setAuthTag(tag); const decrypted = Buffer.concat([ decipher.update(encrypted), decipher.final() ]); return JSON.parse(decrypted.toString()); } /** * Derive master key for key encryption */ _deriveMasterKey() { const keyMaterial = [ this._generateSystemFingerprint(), 'BigBaseAlpha-HSM-v1.5.0', process.env.BIGBASE_HSM_SEED || 'default-seed-change-in-production' ].join('::'); return crypto.pbkdf2Sync(keyMaterial, 'hsm-salt', this.config.iterations, 32, 'sha256'); } /** * Backup key to secure location */ async _backupKey(keyId, keyData) { const backupDir = path.join(this.config.secureStorePath, 'backups'); if (!fs.existsSync(backupDir)) { fs.mkdirSync(backupDir, { mode: 0o700 }); } const backupFile = path.join(backupDir, `${keyId}_${Date.now()}.backup`); fs.writeFileSync(backupFile, JSON.stringify(keyData), { mode: 0o600 }); } /** * Log access for audit trail */ _logAccess(operation, keyId) { const logEntry = { timestamp: Date.now(), operation, keyId, ip: 'localhost', // Offline mode userAgent: 'BigBaseAlpha-HSM/1.5.0' }; this.accessLog.push(logEntry); // Keep only last 1000 entries if (this.accessLog.length > 1000) { this.accessLog = this.accessLog.slice(-1000); } this.emit('hsm:access_logged', logEntry); } /** * Validate HSM is initialized */ _validateInitialized() { if (!this.isInitialized) { throw new Error('HSM not initialized'); } if (this.tamperFlags.size > 0) { throw new Error(`HSM compromised: ${Array.from(this.tamperFlags).join(', ')}`); } } /** * Get HSM status and statistics */ getStatus() { return { initialized: this.isInitialized, keysCount: this.keyStore.size, tamperFlags: Array.from(this.tamperFlags), accessLogSize: this.accessLog.length, lastHealthCheck: this.lastHealthCheck, config: { algorithm: this.config.algorithm, keySize: this.config.keySize, tamperDetection: this.config.tamperDetection } }; } /** * Export audit log */ exportAuditLog() { return { exportTime: Date.now(), entries: [...this.accessLog], hsmStatus: this.getStatus() }; } /** * Shutdown HSM securely */ async shutdown() { this.emit('hsm:shutting_down'); // Clear sensitive data from memory this.keyStore.clear(); this.accessLog.length = 0; this.tamperFlags.clear(); this.isInitialized = false; this.emit('hsm:shutdown_complete'); this.logger.success('BigBaseAlpha HSM shutdown complete'); } } export { OfflineHSM };