const crypto = require('crypto'); const logger = require('./logger'); class Encryption { constructor() { this.algorithm = 'aes-256-gcm'; this.key = Buffer.from(process.env.ENCRYPTION_KEY || '', 'hex'); this.ivLength = 16; this.saltLength = 64; this.tagLength = 16; } encrypt(text) { try { if (!text) return null; // Generate a random initialization vector const iv = crypto.randomBytes(this.ivLength); // Generate a random salt const salt = crypto.randomBytes(this.saltLength); // Create cipher const cipher = crypto.createCipheriv(this.algorithm, this.key, iv); // Encrypt the text let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); // Get the auth tag const tag = cipher.getAuthTag(); // Combine IV, salt, tag, and encrypted text return Buffer.concat([ iv, salt, tag, Buffer.from(encrypted, 'hex') ]).toString('base64'); } catch (error) { logger.error('Encryption error:', error); throw new Error('Encryption failed'); } } decrypt(encryptedData) { try { if (!encryptedData) return null; // Convert from base64 const buffer = Buffer.from(encryptedData, 'base64'); // Extract IV, salt, tag, and encrypted text const iv = buffer.slice(0, this.ivLength); const salt = buffer.slice(this.ivLength, this.ivLength + this.saltLength); const tag = buffer.slice(this.ivLength + this.saltLength, this.ivLength + this.saltLength + this.tagLength); const encrypted = buffer.slice(this.ivLength + this.saltLength + this.tagLength); // Create decipher const decipher = crypto.createDecipheriv(this.algorithm, this.key, iv); decipher.setAuthTag(tag); // Decrypt the text let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } catch (error) { logger.error('Decryption error:', error); throw new Error('Decryption failed'); } } // Hash function for passwords hashPassword(password) { try { const salt = crypto.randomBytes(16).toString('hex'); const hash = crypto.pbkdf2Sync( password, salt, 1000, 64, 'sha512' ).toString('hex'); return `${salt}:${hash}`; } catch (error) { logger.error('Password hashing error:', error); throw new Error('Password hashing failed'); } } // Verify password against hash verifyPassword(password, hashedPassword) { try { const [salt, hash] = hashedPassword.split(':'); const verifyHash = crypto.pbkdf2Sync( password, salt, 1000, 64, 'sha512' ).toString('hex'); return hash === verifyHash; } catch (error) { logger.error('Password verification error:', error); throw new Error('Password verification failed'); } } } module.exports = new Encryption();