Modèle Cryptographique Backend¶
Ce document décrit les aspects cryptographiques spécifiques au backend. Voir le modèle crypto global pour la vue d'ensemble.
Rôle du backend¶
Dans l'architecture Zero-Knowledge, le backend ne voit jamais les données en clair. Son rôle :
- Stocker les documents chiffrés
- Valider les formats (hash, envelopes)
- Signer avec le HSM (certification)
- Horodater via TSA
Services cryptographiques¶
HashService¶
@Injectable()
export class HashService {
// Validation format (pas de recalcul - Zero-K)
isValidHashFormat(hash: string): boolean {
return /^[a-f0-9]{64}$/.test(hash);
}
// Vérification unicité
async isHashUnique(hash: string): Promise<boolean> {
const existing = await this.repo.findOne({ hashDoc: hash });
return !existing;
}
}
HsmService (PKCS#11)¶
@Injectable()
export class HsmService {
private session: pkcs11.Session;
async sign(data: Buffer, keyId: string): Promise<Buffer> {
const mechanism = {
mechanism: pkcs11.MechanismEnum.RSA_PKCS_PSS,
parameter: {
hashAlg: pkcs11.MechanismEnum.SHA256,
mgf: pkcs11.MgfEnum.MGF1_SHA256,
saltLen: 32,
},
};
const key = this.session.find({ label: keyId })[0];
return this.session.sign(mechanism, key, data);
}
async wrapKey(keyToWrap: Buffer, wrappingKeyId: string): Promise<Buffer> {
// AES-KWP (Key Wrap with Padding)
const mechanism = { mechanism: pkcs11.MechanismEnum.AES_KEY_WRAP_PAD };
const wrappingKey = this.session.find({ label: wrappingKeyId })[0];
return this.session.wrapKey(mechanism, wrappingKey, keyToWrap);
}
}
KeyEnvelopeService¶
@Injectable()
export class KeyEnvelopeService {
// Génération Master Envelope pour nouvel utilisateur
async createMasterEnvelope(userId: string): Promise<MasterEnvelope> {
// 1. Générer K_master_user (32 bytes random)
const kMaster = await this.hsmService.generateRandom(32);
// 2. Wrap avec clé HSM
const wrappedKey = await this.hsmService.wrapKey(kMaster, HSM_MASTER_KEY);
// 3. Créer envelope
const envelope: MasterEnvelope = {
version: 'v1',
wrappedKey: wrappedKey.toString('base64'),
keyId: HSM_MASTER_KEY,
algorithm: 'AES-KWP-256',
};
// 4. Stocker pour l'utilisateur
await this.repo.save({ userId, envelope });
// 5. Retourner K_master (sera chiffré côté client)
return { kMaster, envelope };
}
}
Intégration HSM¶
Configuration PKCS#11¶
// config/hsm.config.ts
export const hsmConfig = {
library: '/opt/cloudhsm/lib/libcloudhsm_pkcs11.so',
slot: 0,
pin: process.env.HSM_PIN,
};
Clés HSM¶
| Label | Type | Usage |
|---|---|---|
pv-signing-key | RSA 4096 | Signature documents |
pv-master-wrap-key | AES 256 | Key wrapping |
Horodatage (TSA)¶
@Injectable()
export class TsaService {
async getTimestamp(data: Buffer): Promise<TimestampToken> {
// RFC 3161 timestamp request
const request = this.createTimestampRequest(data);
const response = await axios.post(TSA_URL, request, {
headers: { 'Content-Type': 'application/timestamp-query' },
responseType: 'arraybuffer',
});
return this.parseTimestampResponse(response.data);
}
}
Sécurité des secrets¶
Vault Integration¶
// Secrets récupérés de Vault au démarrage
const secrets = {
hsmPin: await vault.read('secret/hsm/pin'),
dbPassword: await vault.read('secret/db/password'),
jwtSecret: await vault.read('secret/jwt/secret'),
};
Variables d'environnement¶
| Variable | Source | Usage |
|---|---|---|
HSM_PIN | Vault | PIN HSM |
DB_PASSWORD | Vault | Password PostgreSQL |
JWT_SECRET | Vault | Signature JWT |