Aller au contenu

PD-242 — Expression de besoin

Contexte

L'architecture technique v4.1 (doc 42) définit une Recovery Envelope : Enc(K_recovery, K_master_user) permettant a l'utilisateur de recuperer sa cle maitre en cas de perte de device.

Cette promesse est egalement mentionnee dans le pitch investisseurs (doc 43) : "Acces conserve meme apres depart entreprise".

Dependances

Story Description Statut
PD-97 Pipeline crypto zero-knowledge iOS (Argon2id, AES-GCM, HKDF) DONE
PD-98 Stockage K_master dans Keychain iOS (ThisDeviceOnly) DONE

Learnings pertinents (domaine crypto)

  • PD-97 : Hermes (React Native) n'a pas de support WebAssembly — fallback requis pour les operations crypto lourdes
  • PD-97 : JavaScript strings are immutable — memory zeroization is best-effort only
  • PD-33 : Constants must be imported, not redefined inline — inconsistent Associated Data formats break interop
  • PD-99 : Observable contractuel explicite requis (header X-Auth-Protocol)

Besoin fonctionnel

En tant que utilisateur ProbatioVault

Je veux pouvoir recuperer l'acces a mon coffre-fort numerique en cas de perte ou remplacement de mon appareil iOS, Afin de ne jamais perdre mes documents probatoires proteges par la cle maitre K_master.

Description

L'application iOS doit implementer un mecanisme de recovery cryptographique base sur :

  1. Generation d'une phrase de recuperation (BIP-39 24 mots, 256 bits d'entropie)
  2. Derivation d'une cle de recovery (K_recovery) via HKDF-SHA3-256
  3. Creation d'une enveloppe de recovery : Enc(K_recovery, K_master_user)
  4. Stockage zero-knowledge de l'enveloppe cote backend (seul le ciphertext est stocke)
  5. Flux de restauration sur nouveau device via saisie de la phrase

Flux utilisateur

Flux 1 : Creation de la recovery (onboarding obligatoire)

1. L'utilisateur cree son compte ProbatioVault
2. K_master_user est generee et stockee dans le Keychain iOS (PD-98)
3. L'application genere une phrase BIP-39 de 24 mots (CSPRNG local)
4. L'application affiche la phrase et demande a l'utilisateur de la sauvegarder
5. L'utilisateur DOIT re-saisir les 24 mots complets pour confirmer
6. K_recovery est derivee : HKDF-SHA3-256(seed, salt="ProbatioVault::Recovery::v1", info=user_id)
7. L'enveloppe est creee : Recovery_Envelope = Enc_AES-256-GCM(K_recovery, K_master_user)
8. Un hash de verification est genere : H_verify = SHA3-256(K_recovery || user_id)
9. Recovery_Envelope + H_verify sont envoyes au backend (zero-knowledge)
10. K_recovery est detruite en memoire IMMEDIATEMENT
11. La phrase n'est JAMAIS stockee

Flux 2 : Restauration sur nouveau device

1. L'utilisateur installe ProbatioVault sur un nouveau device
2. L'application detecte l'absence de K_master dans le Keychain local
3. L'utilisateur choisit "Recuperer mon coffre"
4. L'utilisateur saisit ses 24 mots
5. K_recovery est derivee localement (meme parametres)
6. H_verify_candidate = SHA3-256(K_recovery || user_id)
7. L'application demande H_verify au backend et compare
8. Si match : l'application demande Recovery_Envelope au backend
9. K_master_user = Dec_AES-256-GCM(K_recovery, Recovery_Envelope)
10. K_master_user est stockee dans le nouveau Keychain (PD-98)
11. K_recovery est detruite en memoire IMMEDIATEMENT
12. L'utilisateur recupere l'acces a son coffre

Flux 3 : Regeneration de phrase (sur demande utilisateur)

1. L'utilisateur demande a regenerer sa phrase de recovery
2. L'application demande l'authentification forte (biometrie + password)
3. Une nouvelle phrase BIP-39 de 24 mots est generee
4. L'utilisateur DOIT re-saisir les 24 mots complets
5. Une nouvelle K_recovery est derivee
6. Une nouvelle Recovery_Envelope est creee
7. L'ancienne Recovery_Envelope est invalidee cote backend
8. Nouvelle Recovery_Envelope + H_verify envoyes au backend
9. Nouvelle K_recovery detruite IMMEDIATEMENT

Invariants de securite

ID Invariant Type
INV-242-01 K_recovery ne transite JAMAIS en clair sur le reseau SEC
INV-242-02 La phrase de recuperation n'est JAMAIS stockee (ni local, ni backend) SEC
INV-242-03 K_recovery est detruite en memoire IMMEDIATEMENT apres usage SEC
INV-242-04 Le backend ne peut PAS dechiffrer K_master_user (zero-knowledge) SEC
INV-242-05 L'entropie de la phrase est de 256 bits minimum (BIP-39 24 mots) SEC
INV-242-06 La derivation utilise HKDF-SHA3-256 avec domain separation CRYPTO
INV-242-07 Le chiffrement de l'enveloppe utilise AES-256-GCM (AEAD) CRYPTO
INV-242-08 La verification de phrase utilise un hash sans exposer K_recovery SEC
INV-242-09 L'onboarding EXIGE la confirmation complete des 24 mots UX
INV-242-10 Un changement de device DECLENCHE automatiquement le flux recovery ARCH

Parametres cryptographiques

Parametre Valeur Reference
Phrase format BIP-39 (24 mots, 256 bits) BIP-0039
Derivation K_recovery HKDF-SHA3-256 RFC 5869 + FIPS 202
HKDF salt "ProbatioVault::Recovery::v1" Domain separation
HKDF info user_id Context binding
HKDF output length 32 bytes (256 bits) Coherence K_master
Chiffrement envelope AES-256-GCM NIST SP 800-38D
GCM nonce 96 bits (random) Best practice
Hash verification SHA3-256(K_recovery || user_id) FIPS 202

Perimetre

Inclus

  • Generation phrase BIP-39 24 mots (CSPRNG local)
  • Derivation K_recovery via HKDF-SHA3-256
  • Creation Recovery_Envelope (AES-256-GCM)
  • Hash de verification H_verify
  • API backend pour stocker/recuperer l'envelope (zero-knowledge)
  • Flux de confirmation (re-saisie 24 mots)
  • Flux de restauration sur nouveau device
  • Flux de regeneration sur demande
  • Destruction memoire K_recovery apres usage
  • Tests avec vecteurs BIP-39 officiels

Exclu

  • Stockage iCloud de l'envelope (decision : backend only)
  • Rotation automatique de l'envelope
  • Shamir Secret Sharing (2-of-3) — future story
  • Mode enterprise custody — future story
  • Implementation Android/Web — hors scope iOS

Criteres d'acceptation preliminaires

ID Critere Mesurable
CA-242-01 La phrase generee est valide BIP-39 (checksum correct) Oui (lib validation)
CA-242-02 K_recovery derivee est deterministe (meme phrase = meme cle) Oui (vecteurs)
CA-242-03 L'envelope peut etre dechiffree avec la phrase originale Oui (test E2E)
CA-242-04 Une phrase incorrecte ne permet PAS de dechiffrer l'envelope Oui (test negatif)
CA-242-05 H_verify permet de detecter une phrase incorrecte AVANT dechiffrement Oui (test)
CA-242-06 K_recovery n'apparait dans aucun log/trace Oui (audit logs)
CA-242-07 La re-saisie des 24 mots est obligatoire a l'onboarding Oui (test E2E)
CA-242-08 Le flux recovery restaure K_master sur un device vierge Oui (test E2E)
CA-242-09 La regeneration invalide l'ancienne envelope Oui (test backend)
CA-242-10 Les operations crypto n'excedent pas 3s sur iPhone 12+ Oui (benchmark)

Risques identifies

Risque Impact Mitigation
Utilisateur ne sauvegarde pas sa phrase Perte definitive du coffre Confirmation obligatoire + UX claire
Phrase interceptee lors de l'affichage Compromission totale Screenshot bloque, timeout affichage
Memory leak de K_recovery Compromission Zeroization best-effort + audit
Backend compromis Fuite des envelopes Zero-knowledge : envelopes inutiles sans phrase
Entropie CSPRNG faible Phrase predictible iOS SecRandomCopyBytes audite

Questions ouvertes (a clarifier en spec)

  1. Timeout affichage phrase : combien de temps avant masquage automatique ?
  2. Blocage screenshot : technique iOS disponible (FLAG_SECURE equivalent) ?
  3. Rate limiting : combien de tentatives de restauration avant blocage ?
  4. Observabilite : quels evenements remonter au backend (sans compromettre ZK) ?
  5. Migration future Android : l'envelope iOS sera-t-elle portable ?

References

  • Architecture technique v4.1 (doc 42) — Section Recovery Envelope
  • Specifications techniques v2.1 (doc 43) — HKDF, AES-GCM
  • BIP-0039 : Mnemonic code for generating deterministic keys
  • RFC 5869 : HMAC-based Extract-and-Expand Key Derivation Function
  • FIPS 202 : SHA-3 Standard
  • NIST SP 800-38D : Recommendation for Block Cipher Modes of Operation: GCM
  • PD-97 : Pipeline crypto zero-knowledge iOS
  • PD-98 : Stockage K_master dans Keychain iOS