Comment leggit protège vos données dans les coffres post-mortem.
Quand vous écrivez un mot de passe ou ajoutez un fichier dans un coffre personnel, leggit applique le pattern envelope encryption : le contenu lui-même n'est chiffré qu'une seule fois, avec une clé éphémère ; cette petite clé est ensuite "emballée" (wrappée) pour chaque destinataire séparément.
crypto_box_seal. On obtient donc un seul cipher de contenu
+ N petits "wraps" de la DEK (~80 octets chacun). Pour vous-même, votre DEK
est aussi wrappée avec votre KEK (clé maître dérivée de votre mot de passe).Pourquoi cette dichotomie ? Le chiffrement symétrique (DEK + cipher) est rapide même pour des fichiers de 100 Mo, mais une clé symétrique ne peut pas être partagée telle quelle. Le chiffrement asymétrique (X25519) sait partager une clé entre interlocuteurs sans secret commun préalable, mais il serait trop lent pour chiffrer des Mo de données. On combine donc les deux : symétrique pour le contenu, asymétrique pour la DEK.
Garantie technique : sous réserve d'intégrité du code JavaScript servi (vérifiable via les hashes SRI ci-dessous), nos administrateurs ne peuvent pas accéder à vos données tant qu'ils ne se substituent pas au navigateur.
| Fonctionnalité | Mode | Commentaire |
|---|---|---|
| Coffres personnels — items texte | E2EE actif | Chiffrement + déchiffrement dans le navigateur (Phase 2) |
| Coffres personnels — fichiers chunked | E2EE actif | Upload chunké 1 MiB chiffré navigateur, download chunké déchiffré navigateur (Phase 3) |
| Ajout destinataire (E2EE) avec rewrap | E2EE actif | Modale re-auth + rewrap immédiat browser-side pour chaque item du coffre (Phase 4) |
| Migration auto items legacy → E2EE | E2EE actif | Migration progressive en arrière-plan au login, transactions atomiques (Phase 5) |
| Audit logs sensibles (titres, previews) | E2EE actif | Détails sensibles chiffrés par votre KEK — seul vous pouvez les lire (Phase 6) |
| Export RGPD self-service | E2EE manifest | Manifest fourni au navigateur, déchiffrement local pour le ZIP (Phase 6) |
| Coffres familiaux — items texte | E2EE actif | Phase 9 livrée : les items texte des coffres familiaux sont chiffrés dans le navigateur du proprio avec une clé éphémère ; chaque membre accepté reçoit une copie de cette clé scellée via X25519 box_seal. Le serveur ne voit qu'un cipher opaque + N wraps. |
| Coffres familiaux — fichiers chunked | E2EE actif | Phase 10 livrée : les fichiers familiaux jusqu'à 100 Mo sont chiffrés par chunks (1 MiB, secretstream_xchacha20poly1305) dans le navigateur, uploadés vers /api?action=fam_upload_chunk_e2ee, et déchiffrés navigateur-side au download via Blob URL. Chaque membre accepté reçoit son wrap personnel box_seal. |
| Coffres familiaux — rewrap automatique au login | E2EE actif | Phase 10 livrée : quand un membre invité accepte tardivement (proprio déconnecté), au prochain login du proprio le handler coffre-familial-rewrap-handler.js détecte les wraps manquants, les produit via le Worker (box_seal pour chaque cible), et les POST au serveur. Transparent pour l'utilisateur. |
| Coffres familiaux — migration items legacy | E2EE actif | Phase 10 livrée : les items texte créés avant Phase 9 (en server-v1) sont migrés en E2EE au prochain login du proprio. Pattern identique à Phase 5 pour les coffres personnels, adapté pour les wraps multi-membres famille_member. |
| Crypto-wallets (seed BIP-39 + image table substitution) | E2EE actif | Phase 8 livrée : la seed (24 mots) et l'image de table de substitution sont chiffrées dans le navigateur via le Web Worker (XChaCha20-Poly1305 pour le texte, secretstream chunked pour l'image). Le serveur ne voit que des cipher blobs opaques. Pour les wallets PARANOIA, la seed était déjà E2EE par design (Shamir M-of-N + box_seal X25519 vers dépositaires) — libsodium est maintenant servi en local au lieu du CDN pour cohérence anti-supply-chain. |
| Messages programmés post-mortem | Serveur (par design) | Le serveur DOIT déchiffrer pour envoyer l'email le jour J — pas possible en pur E2EE. |
| Héritage (post-mortem release) | Serveur (par design) | Combinaison Shamir + déchiffrement session-side après quorum. Items E2EE encore lisibles via wraps recipient. |
XChaCha20-Poly1305-IETF (nonce 24 octets, anti-rejeu)Argon2id13 (memory-hard, anti-GPU)X25519 + crypto_box_seal (sealed box)secretstream_xchacha20poly1305 (state-based, anti-truncation)SHA-256 via WebCrypto API nativelibsodium-wrappers 0.7.13 servie
en local depuis nos serveurs (pas de CDN externe — anti-supply-chain).
Hash SRI vérifiable. Le Web Worker l'importe via importScripts en chemin relatif.dek_fingerprint
(sinon un attaquant qui contrôle le navigateur pourrait injecter sa propre DEK
dans un wrap parasite).id_recipient doivent appartenir à la whitelist du coffre.Chaque script JS de la chaîne crypto est servi avec un hash SRI (Subresource Integrity). Le navigateur refuse d'exécuter le script si le hash diffère. Vous pouvez recalculer ces hashes localement et les comparer :
openssl dgst -sha384 -binary fichier.js | openssl base64 -A # ou shasum -a 384 fichier.js | xxd -r -p | base64
| Fichier | Description | SHA-384 (base64) | Taille |
|---|---|---|---|
| assets/js/coffre-crypto-bootstrap.js | Bootstrap E2EE (détection + chargement) | sha384-AfW/aEqir+7svE+/indeiv3ht5Twt9E2qkz0xZ+KvS4r3zdveUTVzZ8KUtnG8JbR | 8671 o |
| assets/js/coffre-crypto.js | Interface main thread (postMessage Worker) | sha384-yFsAX7p5vk7VogkqrOITcUTOSA+Q+pbDjGNauDxZgoEPDB8y4GDtYBzj9I7nnTbL | 23925 o |
| assets/js/coffre-crypto-worker.js | Worker Web — détient les clés en RAM isolée | sha384-GFinkrLu5sRiQBeA5RAHub6fvnDfHMBxlL9/Nx+IlrPew9YP2W3r0TQP+NMurmIZ | 43785 o |
| assets/js/coffre-form-handler.js | Handler form add_text (Phase 2) | sha384-DV4FbZoHzzGn1wmcQfvMd11mmu4DiiUuKx2ncPZdbDP4F7EatWfBWq3qNdLVPVVF | 10055 o |
| assets/js/coffre-file-handler.js | Handler upload chunked (Phase 3) | sha384-sfPTr6byk+xZoh2kfH2MB8LMFwnhr+XclVNSptceVhiXYX27hRwSVasV5gcUG/p1 | 24569 o |
| assets/js/coffre-reauth-handler.js | Handler reauth + rewrap (Phase 4) | sha384-uZ8kxrxbTrZe3TXrkW7WbaKeAUTr2dS83dypHI0xOu9Tss7TZ2LY8XZxopv8lsCJ | 18673 o |
| assets/js/coffre-migration-handler.js | Handler migration lazy (Phase 5) | sha384-W9vNv5FKMOjdUx9Dn9xF53bvKCU/pfpW7H/1ziueazEncufJA8XeXaEqod6msx/e | 9654 o |
En mode E2EE, leggit ne peut techniquement pas répondre à un droit d'accès classique : nous n'avons pas accès à vos données.
Le droit d'accès s'exerce via un export self-service depuis votre compte : votre navigateur récupère tous vos coffres + items + fichiers, déchiffre via le Worker, et produit un fichier ZIP local que vous téléchargez. Le serveur ne voit que des blobs chiffrés transiter.
Manifest généré le 2026-06-01 00:12:36 —
version applicative 0.1.0