/** * Chiffrement AES-256-GCM symétrique. * Utilisé pour stocker les mots de passe SMTP et secrets Microsoft Graph en BDD. * La clé est dérivée de APP_SECRET (variable d'environnement). */ import crypto from 'crypto'; import { config } from './config'; const ALGORITHM = 'aes-256-gcm'; const IV_LENGTH = 16; const TAG_LENGTH = 16; function getKey(): Buffer { return crypto.createHash('sha256').update(config.appSecret).digest(); } /** * Chiffre une chaîne de texte. * Retourne une chaîne base64 : iv (16) + tag (16) + ciphertext. */ export function encrypt(plaintext: string): string { const iv = crypto.randomBytes(IV_LENGTH); const cipher = crypto.createCipheriv(ALGORITHM, getKey(), iv); const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]); const tag = cipher.getAuthTag(); return Buffer.concat([iv, tag, encrypted]).toString('base64'); } /** * Déchiffre une chaîne encodée en base64 produite par encrypt(). */ export function decrypt(encoded: string): string { const data = Buffer.from(encoded, 'base64'); const iv = data.subarray(0, IV_LENGTH); const tag = data.subarray(IV_LENGTH, IV_LENGTH + TAG_LENGTH); const enc = data.subarray(IV_LENGTH + TAG_LENGTH); const decipher = crypto.createDecipheriv(ALGORITHM, getKey(), iv); decipher.setAuthTag(tag); return decipher.update(enc).toString('utf8') + decipher.final('utf8'); }