ajout envoi smtp (paramètres, test envois, envoi à 1 participant). protège vue mot de passe
- ajout filtre page statistiques
This commit is contained in:
73
src/lib/encryption.ts
Normal file
73
src/lib/encryption.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { createCipheriv, createDecipheriv, randomBytes, pbkdf2Sync } from 'crypto';
|
||||
|
||||
// Clé de chiffrement dérivée de la clé Supabase
|
||||
const deriveKey = (): Buffer => {
|
||||
const salt = process.env.SUPABASE_ANON_KEY || 'default-salt';
|
||||
return pbkdf2Sync(salt, 'mes-budgets-participatifs', 100000, 32, 'sha256');
|
||||
};
|
||||
|
||||
export const encryptionService = {
|
||||
/**
|
||||
* Chiffre une valeur avec AES-256-GCM
|
||||
*/
|
||||
encrypt(value: string): string {
|
||||
if (!value) return '';
|
||||
|
||||
const key = deriveKey();
|
||||
const iv = randomBytes(16);
|
||||
const cipher = createCipheriv('aes-256-gcm', key, iv);
|
||||
|
||||
let encrypted = cipher.update(value, 'utf8', 'hex');
|
||||
encrypted += cipher.final('hex');
|
||||
|
||||
const authTag = cipher.getAuthTag();
|
||||
|
||||
// Format: iv:authTag:encryptedData
|
||||
return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
|
||||
},
|
||||
|
||||
/**
|
||||
* Déchiffre une valeur chiffrée avec AES-256-GCM
|
||||
*/
|
||||
decrypt(encryptedValue: string): string {
|
||||
if (!encryptedValue) return '';
|
||||
|
||||
try {
|
||||
const parts = encryptedValue.split(':');
|
||||
if (parts.length !== 3) {
|
||||
throw new Error('Format de chiffrement invalide');
|
||||
}
|
||||
|
||||
const [ivHex, authTagHex, encryptedData] = parts;
|
||||
const key = deriveKey();
|
||||
const iv = Buffer.from(ivHex, 'hex');
|
||||
const authTag = Buffer.from(authTagHex, 'hex');
|
||||
|
||||
const decipher = createDecipheriv('aes-256-gcm', key, iv);
|
||||
decipher.setAuthTag(authTag);
|
||||
|
||||
let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
|
||||
decrypted += decipher.final('utf8');
|
||||
|
||||
return decrypted;
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du déchiffrement:', error);
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Vérifie si une valeur est chiffrée
|
||||
*/
|
||||
isEncrypted(value: string): boolean {
|
||||
return value && value.includes(':') && value.split(':').length === 3;
|
||||
},
|
||||
|
||||
/**
|
||||
* Masque une valeur pour l'affichage
|
||||
*/
|
||||
mask(value: string, maskChar: string = '•'): string {
|
||||
if (!value) return '';
|
||||
return maskChar.repeat(Math.min(value.length, 8));
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user