spurrin-backend/src/utils/encryption.js
2025-06-09 11:11:52 +05:30

113 lines
3.6 KiB
JavaScript

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();