Aller au contenu

PD-97 — Plan d'implémentation


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

Objectif

Implémenter le chiffrement AES-256-GCM client-side pour garantir le modèle Zero-Knowledge (le serveur ne voit jamais les données en clair).

Choix techniques retenus

  • Algorithme : AES-256-GCM (NIST SP 800-38D)
  • Bibliothèque : @noble/ciphers (pure JS, audité)
  • IV : 12 bytes aléatoires par opération (CSPRNG)
  • AAD : Support optionnel pour données associées
  • Format : IV (12) || Ciphertext || AuthTag (16)

Architecture ciblée

src/crypto/
├── aes-gcm.ts          # Chiffrement/déchiffrement AES-256-GCM
├── envelope.ts         # Gestion enveloppes K_master
├── constants.ts        # Constantes crypto
├── types.ts            # Types TypeScript
├── utils.ts            # Helpers (hex, bytes)
├── zeroize.ts          # Effacement mémoire
└── index.ts            # Exports publics

src/hooks/
└── useCrypto.ts        # Hook React pour crypto

Découpage technique

Phase 1 : Primitives AES-GCM

  1. Implémenter encrypt(key, plaintext, aad?) :
  2. Générer IV 12 bytes via expo-crypto
  3. Chiffrer avec @noble/ciphers gcm
  4. Retourner format compact (IV || CT || Tag)

  5. Implémenter decrypt(key, ciphertext, aad?) :

  6. Extraire IV (12 premiers bytes)
  7. Déchiffrer et vérifier tag
  8. Retourner plaintext

  9. Valider clé 32 bytes, IV 12 bytes

Phase 2 : Gestion enveloppes

  1. Implémenter createMasterEnvelope(kMaster, kEncryption) :
  2. Chiffrer K_master avec K_encryption
  3. Retourner enveloppe (IV + ciphertext + tag)

  4. Implémenter openMasterEnvelope(envelope, kEncryption) :

  5. Déchiffrer enveloppe
  6. Retourner K_master

  7. Support enveloppes device et recovery

Phase 3 : Chiffrement documents

  1. Implémenter encryptDocument(plaintext, kDoc) :
  2. Chiffrer contenu avec K_doc
  3. Retourner format standard

  4. Implémenter decryptDocument(ciphertext, kDoc) :

  5. Déchiffrer et vérifier intégrité
  6. Retourner contenu original

Phase 4 : Sécurité mémoire

  1. Implémenter zeroize(buffer) :
  2. Remplir buffer avec zéros
  3. Appel explicite GC si disponible

  4. Pattern usage : try/finally avec zeroize

  5. Documenter limitations JS (strings immutables)

Phase 5 : Hook React

  1. Implémenter useCrypto() :
  2. Accès aux fonctions encrypt/decrypt
  3. Gestion état loading/error
  4. Intégration avec useAuth pour K_master

Phase 6 : Tests

  1. Tests vecteurs NIST SP 800-38D
  2. Tests intégrité (modification → échec)
  3. Tests pipeline complet (encrypt → decrypt)
  4. Tests edge cases (données vides, grandes tailles)

Points de vigilance

  • IV unique : JAMAIS réutiliser un IV avec la même clé
  • Tag size : Toujours 16 bytes (128 bits) pour GCM
  • Memory : Effacer clés et plaintexts après usage
  • Expo Go : @noble/ciphers fonctionne sans WebAssembly

Hors périmètre

  • Dérivation des clés (→ PD-33, PD-34)
  • Stockage K_master (→ PD-98)
  • Transmission au serveur (→ API documents)