PD-98 — Stockage sécurisé de K_master dans le Keychain iOS¶
📚 Navigation User Story
| Document | | | ---------- | -- | | 📋 **Spécification** | *(ce document)* | | 🛠️ [Plan d'implémentation](PD-98-plan.md) | | | ✅ [Critères d'acceptation](PD-98-acceptability.md) | | | 📝 [Retour d'expérience](PD-98-rex.md) | | [← Retour à mobile-ios](../PD-195-epic.md) · [↑ Index User Story](index.md)Références¶
- EPIC : MOBILE-IOS
- JIRA : PD-98
- Repo(s) concernés : mobile-ios
Objectif¶
Permettre le stockage local sécurisé de la clé maître utilisateur (K_master) dans le Keychain iOS, de manière non exportable, non synchronisable et accessible uniquement lorsque l'appareil est déverrouillé, afin de garantir la confidentialité et l'intégrité du modèle cryptographique côté client.
Description fonctionnelle¶
L'application iOS doit stocker la clé maître utilisateur (K_master) dans le Keychain du système, en s'appuyant sur les mécanismes de sécurité natifs d'iOS.
La clé stockée :
- n'est accessible que lorsque l'appareil est déverrouillé ;
- est liée exclusivement au device courant ;
- ne peut pas être exportée, synchronisée ou restaurée sur un autre appareil ;
- peut être lue, supprimée ou vérifiée par l'application dans le cadre de ses flux normaux (initialisation, déverrouillage, logout).
Aucune information sensible liée à K_master ne doit être exposée dans les logs, l'interface utilisateur ou les traces techniques.
Diagrammes¶
Cycle de vie de K_master dans le Keychain¶
K_master traverse trois etats sur le device. Les transitions sont declenchees par les operations CRUD du service keychainStorage. Les contraintes de securite (non-exportabilite, non-synchronisation) s'appliquent a l'etat STORED.
stateDiagram-v2
[*] --> ABSENT : premier lancement
ABSENT --> STORED : storeMasterKey(kMaster)\n[Contrainte : WHEN_UNLOCKED_THIS_DEVICE_ONLY]
STORED --> ABSENT : deleteMasterKey()\n[logout / reset utilisateur]
STORED --> STORED : storeMasterKey(kMaster)\n[ecrasement idempotent]
STORED --> INACCESSIBLE : appareil verrouille
INACCESSIBLE --> STORED : appareil deverrouille
ABSENT --> ABSENT : deleteMasterKey()\n[idempotent — pas d'erreur]
note right of STORED
- Lie au device courant (ThisDeviceOnly)
- Non exportable, non synchronisable
- Accessible uniquement device deverrouille
Ref : Contraintes Securite, Conformite iOS
end note
note right of INACCESSIBLE
getMasterKey() → DEVICE_LOCKED
Ref : Contraintes Securite
end note Flux de stockage et lecture de K_master¶
Le diagramme ci-dessous detaille les interactions entre l'application, le service de stockage Keychain et le Keychain iOS natif lors des operations de stockage (store) et de lecture (get). Les validations de taille (32 bytes / 256 bits) et l'encodage Base64 sont realises par le service avant tout acces au Keychain.
sequenceDiagram
participant App as Application iOS
participant KS as keychainStorage
participant SS as expo-secure-store
participant KC as iOS Keychain
note over App,KC: --- Stockage de K_master ---
App->>KS: storeMasterKey(kMaster: Uint8Array)
KS->>KS: valider taille == 32 bytes
alt taille invalide
KS-->>App: KeychainError.INVALID_KEY_SIZE
end
KS->>KS: uint8ToBase64(kMaster)
KS->>SS: setItemAsync(key, b64, options)
note right of SS: options.keychainAccessible =<br/>WHEN_UNLOCKED_THIS_DEVICE_ONLY
SS->>KC: SecItemAdd / SecItemUpdate
KC-->>SS: OSStatus
SS-->>KS: void | error
alt erreur Keychain
KS->>KS: mapError(error)
KS-->>App: KeychainError
end
KS->>KS: clearBuffer(b64)
KS-->>App: KeychainResult<void>
note over App,KC: --- Lecture de K_master ---
App->>KS: getMasterKey()
KS->>SS: getItemAsync(key, options)
SS->>KC: SecItemCopyMatching
alt appareil verrouille
KC-->>SS: errSecInteractionNotAllowed
SS-->>KS: error
KS-->>App: KeychainError.DEVICE_LOCKED
end
alt cle absente
KC-->>SS: errSecItemNotFound
SS-->>KS: null
KS-->>App: KeychainError.NOT_FOUND
end
KC-->>SS: b64 data
SS-->>KS: b64 string
KS->>KS: base64ToUint8(b64)
KS->>KS: valider taille == 32 bytes
KS->>KS: clearBuffer(b64)
KS-->>App: KeychainResult<Uint8Array> Périmètre¶
Inclus¶
- Stockage de K_master dans le Keychain iOS.
- Accessibilité limitée à l'état "appareil déverrouillé".
- Non-migrabilité de la clé vers un autre appareil.
- Lecture sécurisée de K_master par l'application.
- Suppression explicite de K_master (logout, reset utilisateur).
- Vérification de la présence d'une clé stockée.
- Gestion fonctionnelle des erreurs liées à l'accès Keychain.
- Documentation du mécanisme et de ses limites de sécurité.
Exclu¶
- Implémentation Android ou autre plateforme.
- Synchronisation via iCloud / Keychain partagé.
- Stockage de secours (fallback) dans un autre mécanisme local.
- Gestion multi-comptes ou multi-profils.
- Exposition ou export de K_master sous quelque forme que ce soit.
Contraintes¶
- Sécurité
- K_master ne doit jamais être stockée en clair hors du Keychain.
- La clé ne doit jamais être loggée, encodée ou affichée.
- L'attribut "ThisDeviceOnly" doit empêcher toute restauration sur un autre device.
-
Aucun mécanisme de stockage alternatif ne doit être utilisé en cas d'échec.
-
Conformité iOS
- Utilisation exclusive des mécanismes Keychain supportés par iOS.
- Respect des attributs de sécurité fournis par le système.
-
Compatibilité avec la version iOS cible de l'application.
-
UX
- Les erreurs d'accès à la clé doivent être traduites en messages compréhensibles.
-
Les mécanismes biométriques existants peuvent être utilisés sans modifier le parcours utilisateur.
-
Robustesse
- Les opérations de lecture et suppression doivent être idempotentes.
- L'effacement mémoire des buffers utilisés est réalisé au mieux après usage.
Hypothèses¶
- L'application iOS dispose déjà d'un flux de création et d'utilisation de K_master.
- Les bibliothèques utilisées permettent l'accès aux attributs Keychain requis.
- Le modèle cryptographique suppose une seule clé maître par profil local.
- Les mécanismes biométriques (Face ID / Touch ID) sont optionnels et déjà gérés ailleurs dans l'application.
Liens documentaires¶
- Architecture :
- Mobile iOS Security Architecture
- EPIC :
- MOBILE-IOS
- Sécurité :
- Modèle de gestion des clés côté client
- Documentation Keychain iOS (Apple)