# Documentation de l'Initialisation LeCoffre.io ## Vue d'ensemble Le système LeCoffre.io suit un processus d'initialisation en plusieurs étapes pour créer et sécuriser un wallet Bitcoin. Ce document détaille chaque étape du processus, depuis le choix du mode de sécurité jusqu'au pairing réussi et à la récupération des processus. ## Architecture des Stores IndexedDB ### Stores utilisés : - **`pbkdf2keys`** : Stockage des clés PBKDF2 chiffrées par mode de sécurité - **`wallet`** : Stockage du wallet chiffré (device + wallet data) - **`credentials`** : Stockage des credentials de pairing (utilisé uniquement après pairing) - **`processes`** : Stockage des processus de communication - **`labels`** : Stockage des labels de transactions - **`shared_secrets`** : Stockage des secrets partagés - **`unconfirmed_secrets`** : Stockage des secrets non confirmés - **`diffs`** : Stockage des différences de synchronisation - **`data`** : Stockage des données générales ## Flux d'Initialisation Complet ### 1. Démarrage de l'Application **Fichier :** `src/router.ts` → `checkStorageStateAndNavigate()` L'application vérifie l'état du storage pour déterminer l'étape suivante : ```typescript // Logique de progression : // - Si pairing → account // - Si date anniversaire → pairing // - Si wallet → birthday-setup // - Si pbkdf2 → wallet-setup // - Sinon → security-setup ``` **États possibles :** 1. **Appareil appairé** → Redirection vers `account` 2. **Date anniversaire configurée** → Redirection vers `home` (pairing) 3. **Wallet existe sans date anniversaire** → Redirection vers `birthday-setup` 4. **Clé PBKDF2 existe** → Redirection vers `wallet-setup` 5. **Aucune configuration** → Redirection vers `security-setup` ### 2. Configuration du Mode de Sécurité **Fichier :** `src/pages/security-setup/security-setup.ts` #### 2.1 Sélection du Mode L'utilisateur choisit parmi les modes disponibles : | Mode | Nom | Description | Niveau de Sécurité | Clé de Chiffrement PBKDF2 | Stockage de la Clé de Chiffrement | |------|-----|-------------|-------------------|---------------------------|-----------------------------------| | `proton-pass` | Proton Pass | Authentification biométrique via Proton Pass | High | Clé WebAuthn générée par le navigateur | Stockée dans le navigateur (WebAuthn credential) | | `os` | Authentificateur OS | Authentification biométrique du système | High | Clé WebAuthn générée par le système | Stockée dans le système d'exploitation | | `otp` | OTP | Code à usage unique (Google Authenticator, etc.) | High | Aucune (clé PBKDF2 stockée en clair) | Secret OTP stocké dans l'application OTP | | `password` | Mot de passe | Chiffrement par mot de passe (non sauvegardé) | Low | Mot de passe utilisateur | Stocké dans le gestionnaire de mots de passe du navigateur | | `none` | Aucune sécurité | Chiffrement avec clé en dur (non recommandé) | Critical | Clé en dur `4NK_DEFAULT_ENCRYPTION_KEY_NOT_SECURE` | Intégrée dans le code (non sécurisé) | #### 2.2 Génération de la Clé PBKDF2 **Fichier :** `src/services/secure-credentials.service.ts` → `generatePBKDF2Key()` Pour chaque mode, une clé PBKDF2 est générée et stockée différemment : ##### Mode `proton-pass` et `os` (WebAuthn) ```typescript // Stockage avec WebAuthn (authentification biométrique) await webAuthnService.storeKeyWithWebAuthn(pbkdf2Key, securityMode); ``` - **Store :** `pbkdf2keys` - **Clé :** `security_mode` (ex: "proton-pass") - **Valeur :** Clé PBKDF2 chiffrée avec WebAuthn - **Authentification :** Biométrique (empreinte, visage, etc.) ##### Mode `otp` ```typescript // Génération du secret OTP const otpSecret = await this.generateOTPSecret(); // Stockage de la clé PBKDF2 en clair await this.storePBKDF2KeyInStore(pbkdf2Key, securityMode); // Affichage du QR code this.displayOTPQRCode(otpSecret); ``` - **Store :** `pbkdf2keys` - **Clé :** `security_mode` ("otp") - **Valeur :** Clé PBKDF2 en clair - **Authentification :** Code OTP généré par l'application ##### Mode `password` ```typescript // Demande du mot de passe utilisateur const userPassword = await this.promptForPasswordWithBrowser(); // Chiffrement de la clé PBKDF2 const encryptedKey = await encryptionService.encrypt(pbkdf2Key, userPassword); // Stockage chiffré await this.storePBKDF2KeyInStore(encryptedKey, securityMode); ``` - **Store :** `pbkdf2keys` - **Clé :** `security_mode` ("password") - **Valeur :** Clé PBKDF2 chiffrée avec le mot de passe utilisateur - **Authentification :** Mot de passe utilisateur (non sauvegardé) ##### Mode `none` ```typescript // Clé de chiffrement en dur const hardcodedKey = '4NK_DEFAULT_ENCRYPTION_KEY_NOT_SECURE'; // Chiffrement avec la clé en dur const encryptedKeyNone = await encryptionService.encrypt(pbkdf2Key, hardcodedKey); // Stockage chiffré await this.storePBKDF2KeyInStore(encryptedKeyNone, securityMode); ``` - **Store :** `pbkdf2keys` - **Clé :** `security_mode` ("none") - **Valeur :** Clé PBKDF2 chiffrée avec clé en dur - **Authentification :** Aucune (non sécurisé) ### 3. Création du Wallet **Fichier :** `src/pages/wallet-setup/wallet-setup.ts` #### 3.1 Récupération de la Clé PBKDF2 Le système teste tous les modes de sécurité pour trouver la clé PBKDF2 valide : ```typescript const allSecurityModes = ['none', 'otp', 'password', 'os', 'proton-pass']; for (const mode of allSecurityModes) { const hasKey = await secureCredentialsService.hasPBKDF2Key(mode); if (hasKey) { const key = await secureCredentialsService.retrievePBKDF2Key(mode); if (key) { currentMode = mode; break; } } } ``` #### 3.2 Génération des Clés du Wallet ```typescript // Génération des clés temporaires const walletData = { scan_sk: encryptionService.generateRandomKey(), spend_key: encryptionService.generateRandomKey(), network: 'signet', state: 'birthday_waiting', created_at: new Date().toISOString() }; ``` #### 3.3 Création du Device via SDK ```typescript // Création du device avec birthday = 0 const spAddress = await services.sdkClient.create_new_device(0, 'signet'); // Génération forcée du wallet const wallet = await services.sdkClient.dump_wallet(); ``` #### 3.4 Stockage Chiffré du Wallet ```typescript // Chiffrement du device const encryptedDevice = await encryptionService.encrypt(deviceString, pbkdf2Key); // Chiffrement du wallet const encryptedWallet = await encryptionService.encrypt(walletString, pbkdf2Key); // Stockage dans le store wallet const walletObject = { pre_id: '1', encrypted_device: encryptedDevice, encrypted_wallet: encryptedWallet }; ``` **Store :** `wallet` **Clé :** `pre_id` ("1") **Valeur :** Objet contenant uniquement des données chiffrées ### 4. Configuration de la Date Anniversaire **Fichier :** `src/pages/birthday-setup/birthday-setup.ts` #### 4.1 Connexion aux Relais ```typescript // Connexion aux relais Bitcoin await services.connectToRelays(); ``` #### 4.2 Mise à Jour de la Date Anniversaire ```typescript // Récupération de la hauteur de bloc actuelle const currentBlockHeight = await services.getCurrentBlockHeight(); // Mise à jour du birthday du device await services.updateDeviceBirthday(currentBlockHeight); ``` #### 4.3 Synchronisation des Processus ```typescript // Restauration des processus depuis la base de données await services.restoreProcessesFromDB(); ``` ### 5. Processus de Pairing **Fichier :** `src/pages/home/home.ts` → `handleMainPairing()` #### 5.1 Vérification du Mode de Sécurité ```typescript const currentMode = await securityModeService.getCurrentMode(); if (!currentMode) { // Afficher le sélecteur de mode de sécurité await showSecurityModeSelector(); return; } ``` #### 5.2 Authentification selon le Mode ##### Mode `proton-pass` et `os` ```typescript // Authentification WebAuthn const credential = await navigator.credentials.get({ publicKey: { challenge: new Uint8Array(32), allowCredentials: [{ id: credentialId, type: 'public-key' }] } }); ``` ##### Mode `otp` ```typescript // Demande du code OTP const otpCode = await this.promptForOTPCode(); // Vérification du code OTP const isValid = await this.verifyOTPCode(otpCode, otpSecret); ``` ##### Mode `password` ```typescript // Demande du mot de passe const password = await this.promptForPassword(); // Déchiffrement de la clé PBKDF2 const pbkdf2Key = await encryptionService.decrypt(encryptedKey, password); ``` ##### Mode `none` ```typescript // Déchiffrement avec la clé en dur const pbkdf2Key = await encryptionService.decrypt(encryptedKey, hardcodedKey); ``` #### 5.3 Génération des Credentials de Pairing ```typescript // Génération des credentials sécurisés const credentialData = await secureCredentialsService.generateSecureCredentials('4nk-secure-password'); // Stockage des credentials dans le store credentials await secureCredentialsService.storeCredentials(credentialData, ''); // Récupération et déchiffrement des credentials const retrievedCredentials = await secureCredentialsService.retrieveCredentials(''); ``` #### 5.4 Création du Processus de Pairing ```typescript // Création du processus via le SDK const pairingResult = await services.createPairingProcess({ spendKey: retrievedCredentials.spendKey, scanKey: retrievedCredentials.scanKey }); ``` ### 6. Récupération des Processus **Fichier :** `src/services/service.ts` → `restoreProcessesFromDB()` #### 6.1 Synchronisation des Processus ```typescript // Récupération des processus depuis la base de données const processes = await processRepo.getAllProcesses(); // Synchronisation avec le réseau for (const process of processes) { await services.syncProcess(process); } ``` #### 6.2 Mise à Jour de l'État de Pairing ```typescript // Vérification de l'état de pairing const isPaired = services.isPaired(); if (isPaired) { // Redirection vers la page account await navigate('account'); } ``` ## Diagramme de Flux ```mermaid graph TD A[Démarrage Application] --> B{Vérification État Storage} B -->|Aucune config| C[Security Setup] B -->|PBKDF2 existe| D[Wallet Setup] B -->|Wallet existe| E[Birthday Setup] B -->|Birthday configuré| F[Pairing] B -->|Appareil appairé| G[Account] C --> C1[Sélection Mode Sécurité] C1 --> C2[Génération Clé PBKDF2] C2 --> C3[Stockage selon Mode] C3 --> D D --> D1[Récupération Clé PBKDF2] D1 --> D2[Création Device SDK] D2 --> D3[Génération Wallet] D3 --> D4[Stockage Chiffré] D4 --> E E --> E1[Connexion Relais] E1 --> E2[Mise à Jour Birthday] E2 --> E3[Synchronisation Processus] E3 --> F F --> F1[Authentification Mode] F1 --> F2[Génération Credentials] F2 --> F3[Création Processus Pairing] F3 --> F4[Récupération Processus] F4 --> G ``` ## Sécurité par Mode ### Mode `proton-pass` et `os` - **Stockage :** Clé PBKDF2 chiffrée avec WebAuthn - **Authentification :** Biométrique (empreinte, visage) - **Sécurité :** Élevée (clé matérielle) ### Mode `otp` - **Stockage :** Clé PBKDF2 en clair - **Authentification :** Code OTP temporaire - **Sécurité :** Élevée (authentification à deux facteurs) ### Mode `password` - **Stockage :** Clé PBKDF2 chiffrée avec mot de passe utilisateur - **Authentification :** Mot de passe utilisateur - **Sécurité :** Faible (dépend de la force du mot de passe) ### Mode `none` - **Stockage :** Clé PBKDF2 chiffrée avec clé en dur - **Authentification :** Aucune - **Sécurité :** Critique (non recommandé) ## Gestion des Erreurs ### Erreurs de Chiffrement - **Clé PBKDF2 introuvable** → Redirection vers `security-setup` - **Échec de déchiffrement** → Demande de réauthentification - **Wallet corrompu** → Recréation du wallet ### Erreurs de Réseau - **Connexion relais échouée** → Retry automatique - **Synchronisation échouée** → Mode hors ligne - **Pairing échoué** → Nouvelle tentative ### Erreurs d'Authentification - **WebAuthn échoué** → Fallback vers autre mode - **OTP invalide** → Nouvelle demande - **Mot de passe incorrect** → Nouvelle tentative ## Points d'Attention 1. **Ordre des modes testés** : `['none', 'otp', 'password', 'os', 'proton-pass']` 2. **Store `credentials`** : Utilisé uniquement après pairing 3. **Clé PBKDF2** : Toujours stockée dans `pbkdf2keys` avec `security_mode` comme clé 4. **Wallet** : Toujours stocké chiffré dans le store `wallet` 5. **Redirection automatique** : 3 secondes après création du wallet vers `birthday-setup` Cette documentation couvre l'ensemble du processus d'initialisation du système LeCoffre.io, depuis la configuration de sécurité jusqu'au pairing réussi et à la récupération des processus.