Aller au contenu

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 :

  1. Stocker les documents chiffrés
  2. Valider les formats (hash, envelopes)
  3. Signer avec le HSM (certification)
  4. 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

Liens