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_atdevice_blacklist: liste des devices révoquésid,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)