Aethel Bot OSS repository! aethel.xyz
bot fun ai discord discord-bot aethel
at dev 2.5 kB view raw
1import crypto from 'crypto'; 2import { API_KEY_ENCRYPTION_SECRET } from '../config'; 3 4const ENCRYPTION_KEY = API_KEY_ENCRYPTION_SECRET; 5const ALGORITHM = 'aes-256-gcm'; 6 7const getEncryptionKey = (): Buffer => { 8 if (ENCRYPTION_KEY.length !== 32) { 9 throw new Error('ENCRYPTION_KEY must be exactly 32 characters long'); 10 } 11 return Buffer.from(ENCRYPTION_KEY, 'utf8'); 12}; 13 14/** 15 * Encrypts a string using AES-256-GCM 16 * @param text The text to encrypt 17 * @returns Base64 encoded encrypted data with IV and auth tag 18 */ 19export const encryptApiKey = (text: string): string => { 20 try { 21 const key = getEncryptionKey(); 22 const iv = crypto.randomBytes(16); 23 24 const cipher = crypto.createCipheriv(ALGORITHM, key, iv); 25 cipher.setAAD(Buffer.from('aethel-api-key', 'utf8')); 26 27 let encrypted = cipher.update(text, 'utf8', 'hex'); 28 encrypted += cipher.final('hex'); 29 30 const authTag = cipher.getAuthTag(); 31 32 const combined = Buffer.concat([iv, authTag, Buffer.from(encrypted, 'hex')]); 33 34 return combined.toString('base64'); 35 } catch { 36 throw new Error('Failed to encrypt API key'); 37 } 38}; 39 40/** 41 * Decrypts a string that was encrypted with encryptApiKey 42 * @param encryptedData Base64 encoded encrypted data 43 * @returns The decrypted text 44 */ 45export const decryptApiKey = (encryptedData: string): string => { 46 try { 47 const key = getEncryptionKey(); 48 const combined = Buffer.from(encryptedData, 'base64'); 49 50 const extractedIv = combined.subarray(0, 16); 51 const authTag = combined.subarray(16, 32); 52 const encrypted = combined.subarray(32); 53 54 const decipher = crypto.createDecipheriv(ALGORITHM, key, extractedIv); 55 decipher.setAAD(Buffer.from('aethel-api-key', 'utf8')); 56 decipher.setAuthTag(authTag); 57 58 let decrypted = decipher.update(encrypted, undefined, 'utf8'); 59 decrypted += decipher.final('utf8'); 60 61 return decrypted; 62 } catch { 63 throw new Error('Failed to decrypt API key'); 64 } 65}; 66 67/** 68 * Generates a secure random encryption key 69 * @returns A 32-character random string suitable for use as ENCRYPTION_KEY 70 */ 71export const generateEncryptionKey = (): string => { 72 return crypto.randomBytes(32).toString('base64').substring(0, 32); 73}; 74 75/** 76 * Validates that an encryption key is properly formatted 77 * @param key The key to validate 78 * @returns True if the key is valid 79 */ 80export const validateEncryptionKey = (key: string): boolean => { 81 return typeof key === 'string' && key.length === 32; 82};