Skip to main content

Cloud API - E2EE Implementation

Implémentation complète du chiffrement de bout en bout.


🔐 Architecture E2EE


🧮 Algorithmes

AES-256-GCM

// src/common/e2ee.module.ts
@Injectable()
export class E2EEncryptionService {
private readonly algorithm = 'aes-256-gcm';
private readonly keyLength = 32;

async deriveKey(password: string, salt: Buffer): Promise<Buffer> {
return new Promise((resolve, reject) => {
scrypt(password, salt, this.keyLength, (err, key) => {
if (err) reject(err);
resolve(key);
});
});
}

async encrypt(data: Buffer | string, password: string): Promise<EncryptedData> {
const salt = randomBytes(16);
const key = await this.deriveKey(password, salt);
const iv = randomBytes(12);

const cipher = createCipheriv(this.algorithm, key, iv);

let encrypted = cipher.update(
typeof data === 'string' ? Buffer.from(data) : data
);
encrypted = Buffer.concat([encrypted, cipher.final()]);

return {
ciphertext: encrypted.toString('base64'),
iv: iv.toString('base64'),
authTag: cipher.getAuthTag().toString('base64'),
salt: salt.toString('base64'),
};
}

async decrypt(encrypted: EncryptedData, password: string): Promise<Buffer> {
const salt = Buffer.from(encrypted.salt, 'base64');
const iv = Buffer.from(encrypted.iv, 'base64');
const authTag = Buffer.from(encrypted.authTag, 'base64');
const ciphertext = Buffer.from(encrypted.ciphertext, 'base64');

const key = await this.deriveKey(password, salt);

const decipher = createDecipheriv(this.algorithm, key, iv);
decipher.setAuthTag(authTag);

let decrypted = decipher.update(ciphertext);
decrypted = Buffer.concat([decrypted, decipher.final()]);

return decrypted;
}
}

🔑 Key Management

Hiérarchie de clés

interface KeyHierarchy {
masterKey: Uint8Array; // Générée localement
derivedKeys: {
workflowDataKey: WrappedKey; // Chiffrée avec master key
agentStateKey: WrappedKey;
settingsKey: WrappedKey;
auditLogSigningKey: SigningKey;
};
}

interface WrappedKey {
encryptedKey: string; // Base64
iv: string; // Base64
authTag: string; // Base64
}

Key Rotation

async function rotateMasterKey(
userId: string,
newMasterKey: Uint8Array,
oldMasterKey: Uint8Array
): Promise<void> {
// 1. Déchiffrer toutes les data keys avec l'ancienne master key
const dataKeys = await unwrapAllDataKeys(oldMasterKey);

// 2. Re-chiffrer avec la nouvelle master key
const rewrappedKeys = await wrapDataKeys(dataKeys, newMasterKey);

// 3. Mettre à jour le stockage
await storeMasterKey(userId, newMasterKey);
await storeDataKeys(userId, rewrappedKeys);

// 4. Notifier les autres appareils
await notifyDevices(userId, 'MASTER_KEY_ROTATED');

// 5. Audit log
await auditLog('MASTER_KEY_ROTATED', { userId });
}

📊 Métriques de sécurité

MétriqueCible
Encryption Strength256 bits
Key DerivationPBKDF2 (100K iterations)
Key ExchangeX25519 (ECDH)
SignatureHMAC-SHA256

Version : 1.0.0