Aller au contenu

PD-35 — Module d'enveloppes de clés (Key Wrapping)


📚 Navigation User Story | Document | | | ---------- | -- | | 📋 **Spécification** | *(ce document)* | | 🛠️ [Plan d'implémentation](PD-35-plan.md) | | | ✅ [Critères d'acceptation](PD-35-acceptability.md) | | | 📝 [Retour d'expérience](PD-35-rex.md) | | [← Retour à crypto-proof](../PD-189-epic.md) · [↑ Index User Story](index.md)

Références

  • EPIC : PD-189 — CRYPTO
  • JIRA : PD-35
  • Repo(s) concernés : backend

Objectif

Mettre en place un module de gestion des enveloppes de clés permettant de protéger, stocker et faire évoluer la clé maître utilisateur (K_master_user) sans jamais re-chiffrer les documents, en s'appuyant sur un mécanisme de key wrapping conforme aux standards.

Ce module doit permettre :

  • la rotation de mot de passe sans impact sur les fichiers WORM ;
  • l'accès multi-devices sécurisé ;
  • la récupération de compte via une clé de secours ;

tout en respectant strictement le modèle zero-knowledge de ProbatioVault.

Description fonctionnelle

Le système doit gérer des enveloppes cryptographiques contenant la clé maître utilisateur (K_master_user), chiffrées avec différentes clés de protection selon l'usage.

Trois types d'enveloppes doivent être supportés :

  • Enveloppe maître Utilisée pour protéger K_master_user avec une clé dérivée du mot de passe, afin de permettre le changement de mot de passe sans re-chiffrer les documents.

  • Enveloppes device Utilisées pour permettre à plusieurs appareils autorisés d'accéder aux documents de l'utilisateur, chaque appareil disposant de sa propre enveloppe.

  • Enveloppe de récupération Utilisée pour restaurer l'accès au compte en cas de perte de tous les appareils et du mot de passe, via une clé de récupération dédiée.

K_master_user reste inchangée pendant toute la durée de vie du compte. Seules les enveloppes sont créées, mises à jour ou révoquées.

Périmètre

Inclus

  • Gestion des enveloppes de clés pour un utilisateur.
  • Support de plusieurs types d'enveloppes (maître, device, récupération).
  • Chiffrement et déchiffrement des enveloppes via un algorithme standardisé.
  • Stockage persistant des enveloppes dans une base sécurisée.
  • Rotation de l'enveloppe maître lors d'un changement de mot de passe.
  • Création et révocation d'enveloppes device.
  • Support d'un mécanisme de récupération de compte.
  • Transactions atomiques garantissant la cohérence des opérations.
  • Isolation stricte des données par utilisateur.
  • Tests fonctionnels et de sécurité du module.

Exclu

  • Génération ou gestion directe des mots de passe.
  • Dérivation cryptographique des clés (traitée dans d'autres User Stories).
  • Gestion des documents ou de leur chiffrement.
  • Gestion des clés HSM.
  • Synchronisation ou export de clés en clair.
  • Interfaces utilisateur de gestion des devices ou de récupération.

Contraintes

  • Sécurité
  • K_master_user ne doit jamais être stockée en clair.
  • Aucune enveloppe ne doit permettre d'accéder à une clé non autorisée.
  • Les clés doivent être effacées de la mémoire après usage.
  • Les appareils révoqués ne doivent plus pouvoir accéder aux enveloppes.
  • Les opérations sensibles doivent être journalisées de manière probatoire.

  • Conformité cryptographique

  • Utilisation d'un algorithme de key wrapping standardisé et reconnu.
  • Conformité aux exigences zero-knowledge du produit.
  • Compatibilité avec les mécanismes probatoires en aval.

  • Robustesse

  • Les opérations critiques doivent être atomiques.
  • Aucune incohérence ne doit subsister en cas d'échec partiel.
  • Le module doit supporter des accès concurrents.

  • Base de données

  • Les enveloppes doivent être isolées par utilisateur.
  • Les contraintes d'unicité et d'intégrité doivent être garanties.
  • Les données doivent être supprimées lors de la suppression d'un compte.

Hypothèses

  • Une clé maître utilisateur unique est générée à la création du compte.
  • Les clés de protection (mot de passe, device, récupération) sont dérivées ou générées par des modules dédiés.
  • La base de données supporte les mécanismes de sécurité requis.
  • Les mécanismes d'audit et de signature des événements sont disponibles via d'autres User Stories.
  • Les documents chiffrés ne doivent jamais être modifiés lors des opérations sur les enveloppes.

Spécifications techniques

Algorithme AES-256-KW (RFC 3394)

Paramètre Valeur
Algorithme AES Key Wrap (RFC 3394)
KEK (Key Encryption Key) 32 bytes (256 bits)
Plaintext (clé à protéger) 32 bytes (256 bits)
Wrapped output 40 bytes (32 + 8 bytes IV)
IV par défaut A6A6A6A6A6A6A6A6

Entities TypeORM

Les enveloppes sont persistées via deux entités principales :

  • key_envelopes : stocke les enveloppes chiffrées (master, device, recovery)
  • id, user_id, type, wrapped_key, created_at, revoked_at
  • device_blacklist : liste des devices révoqués
  • id, user_id, device_id, revoked_at, reason

Diagrammes

Diagramme d'états — Cycle de vie d'une enveloppe

Une enveloppe traverse les états suivants. L'invariant unicité master/recovery impose qu'une seule enveloppe de type master ou recovery soit active par utilisateur à un instant donné. L'invariant blacklist permanente garantit qu'un device révoqué ne peut plus créer de nouvelle enveloppe.

stateDiagram-v2
    [*] --> CREATED : wrap(KEK, K_master_user)
    CREATED --> ACTIVE : persist (transaction atomique)
    ACTIVE --> REVOKED : révocation device\nou rotation master
    REVOKED --> [*]

    note right of CREATED
        wrapped_key = 40 bytes
        (32 + 8 IV RFC 3394)
    end note

    note right of ACTIVE
        Invariant : 1 seule master/recovery
        active par utilisateur
    end note

    note right of REVOKED
        revoked_at NOT NULL
        Invariant : révocation définitive
        (device -> blacklist)
    end note

Séquence — Création d'enveloppe maître (inscription)

Flux nominal lors de la création du compte. L'invariant K_master_user identique impose que la clé maître soit générée une seule fois et ne change jamais. L'invariant zeroization après usage impose l'effacement de toutes les clés (KEK, K_master_user) dans le bloc finally.

sequenceDiagram
    participant Client
    participant Controller as KeyEnvelopeController
    participant Service as KeyEnvelopeService
    participant AesKw as AesKwService
    participant DB as PostgreSQL (vault_secure)

    Client->>Controller: POST /envelopes/master { kek, K_master_user }
    Controller->>Service: createMasterEnvelope(userId, kek, K_master_user)
    Service->>Service: vérifier aucune master active (unicité)
    Service->>AesKw: wrap(kek, K_master_user)
    AesKw->>AesKw: valider KEK 32 bytes, plaintext 32 bytes
    AesKw-->>Service: wrapped_key (40 bytes)
    Service->>DB: INSERT key_envelopes (type=master)
    DB-->>Service: OK
    Service->>Service: zeroize(kek, K_master_user)
    Service-->>Controller: enveloppe créée
    Controller-->>Client: 201 Created

Séquence — Rotation de mot de passe (re-wrap)

L'invariant transaction atomique rotation impose que unwrap / re-wrap / save soient exécutés dans la même transaction. L'invariant K_master_user identique garantit que la clé maître récupérée par unwrap est ré-enveloppée telle quelle avec la nouvelle KEK. L'invariant integrity check AES-KW vérifie les 8 bytes IV à chaque unwrap (détection de KEK invalide).

sequenceDiagram
    participant Client
    participant Service as KeyEnvelopeService
    participant AesKw as AesKwService
    participant DB as PostgreSQL (vault_secure)

    Client->>Service: rotateMasterEnvelope(userId, oldKek, newKek)
    Service->>DB: BEGIN TRANSACTION
    Service->>DB: SELECT wrapped_key WHERE type=master AND revoked_at IS NULL
    DB-->>Service: wrapped_key (40 bytes)
    Service->>AesKw: unwrap(oldKek, wrapped_key)
    AesKw->>AesKw: vérifier IV A6A6A6A6A6A6A6A6 (integrity check)
    AesKw-->>Service: K_master_user (32 bytes)
    Service->>AesKw: wrap(newKek, K_master_user)
    AesKw-->>Service: new_wrapped_key (40 bytes)
    Service->>DB: UPDATE key_envelopes SET revoked_at=NOW() (ancienne)
    Service->>DB: INSERT key_envelopes (type=master, new_wrapped_key)
    Service->>DB: COMMIT
    DB-->>Service: OK
    Service->>Service: zeroize(oldKek, newKek, K_master_user)
    Service-->>Client: rotation OK

Séquence — Révocation d'un device

L'invariant blacklist permanente garantit que le device révoqué est inscrit dans device_blacklist et ne pourra plus créer d'enveloppe.

sequenceDiagram
    participant Client
    participant Service as KeyEnvelopeService
    participant DB as PostgreSQL (vault_secure)

    Client->>Service: revokeDevice(userId, deviceId, reason)
    Service->>DB: BEGIN TRANSACTION
    Service->>DB: UPDATE key_envelopes SET revoked_at=NOW() WHERE deviceId AND type=device
    Service->>DB: INSERT device_blacklist (userId, deviceId, reason)
    Service->>DB: COMMIT
    DB-->>Service: OK
    Service-->>Client: device révoqué

Liens documentaires

  • Architecture :
  • Architecture Cryptographique — Gestion des clés
  • EPIC :
  • PD-189 — CRYPTO
  • Sécurité & conformité :
  • RFC 3394 — AES Key Wrap
  • Spécifications ProbatioVault — Modèle zero-knowledge
  • NF Z42-013 / ISO 14641 (traçabilité des opérations)