Tous les articles

10 min de lecture

Où CardanoWall conserve vos clés dans le navigateur

Dans le navigateur, CardanoWall garde les clés déverrouillées en mémoire de session et n'écrit dans IndexedDB que le texte chiffré du coffre — jamais les graines d'identité ni les clés privées en clair.

Lorsque vous déverrouillez CardanoWall dans le navigateur, la graine déverrouillée et les clés privées qui en dérivent vivent en mémoire de session — la mémoire applicative ordinaire, qui disparaît dès que vous verrouillez, vous déconnectez ou fermez l'onglet. Le stockage persistant du navigateur (IndexedDB, sessionStorage) ne contient que le texte chiffré du coffre et des métadonnées non secrètes. Les graines d'identité et les clés privées dérivées en clair n'y sont jamais écrites.

C'est toute la question. Le navigateur doit détenir du matériel de clé pour signer et déchiffrer localement — c'est ainsi, et pas autrement, que la cryptographie fonctionne. La vraie interrogation n'est jamais « le navigateur peut-il toucher aux clés ? » : il le faut bien. La question est de savoir ces clés résident et ce qui est écrit sur le disque. Le modèle web de CardanoWall est conçu pour que ce qui survit à un rechargement soit du texte chiffré, et non des secrets.

De quoi le navigateur a-t-il besoin pendant qu'une identité est déverrouillée ?

Il a besoin du matériel de clé privée pour le travail que vous êtes réellement en train de faire — et de rien de plus durable que la session elle-même.

Une fois que vous avez déverrouillé une identité, l'application peut avoir à :

  • signer un record Label 309 ;
  • déchiffrer un record scellé qui vous est adressé ;
  • tenter le déchiffrement à l'essai des records scellés entrants pour repérer ceux destinés à votre boîte de réception ;
  • rechiffrer le coffre après l'ajout ou le retrait d'un passkey ;
  • révéler votre graine lorsque vous demandez explicitement à la voir ;
  • reconstruire les caches chiffrés locaux.

Rien de tout cela n'est possible avec les seules clés publiques. Chaque opération exige du matériel privé dérivé de votre graine d'identité. Par conception, ce matériel reste en mémoire de session et est effacé au verrouillage ou à la déconnexion — au mieux des possibilités, pour des raisons que nous abordons plus bas.

Qu'entend-on ici par mémoire de session ?

La mémoire de session est une mémoire applicative temporaire, propre au processus, que l'application abandonne dès la fin de la session de déverrouillage.

Dans l'application web de CardanoWall, la graine active et les clés qui en dérivent sont détenues en dehors de l'état d'interface ordinaire, dans des structures de mémoire interne. L'état réactif de l'interface ne conserve que des faits non secrets : quelle identité est déverrouillée, à quel moment elle l'a été, quelles métadonnées d'enrôlement de passkey sont affichées pendant la configuration. Les octets secrets n'entrent jamais dans cet état réactif.

Cette séparation compte, parce que l'état d'interface ordinaire est la partie d'une application la plus susceptible d'être inspectée, sérialisée, persistée ou transmise par accident à un composant qui la journalise. Le matériel secret mérite une surface plus réduite et délibérément énumérée. Chaque endroit de l'application capable de remettre des octets secrets — la fermeture de signature, les clés de déchiffrement, la sortie de secours pour révéler la graine, le chemin de reconstruction du coffre — est répertorié dans un seul fichier, et chacun renvoie une copie défensive plutôt que le tampon actif.

Le navigateur détient toujours les secrets tant que vous êtes déverrouillé. Ils ne sont simplement pas traités comme des données applicatives normales.

Qu'est-ce qui est écrit dans IndexedDB ?

Le texte chiffré du coffre — les octets mêmes que stocke le serveur, et non les graines qu'ils contiennent.

IndexedDB sert de cache local de votre coffre d'identité chiffré : une ligne par compte, contenant exactement le texte chiffré par age que conserve le serveur. Le mettre en cache permet à l'application de se réhydrater après un rechargement à partir d'une seule pression sur un passkey, sans aller-retour pour récupérer à nouveau le coffre.

Un attaquant qui se contenterait de lire cette base de données locale ne verrait que les octets chiffrés du coffre adressés à vos passkeys — pas des graines en clair. Le cache reste une donnée de service sensible, et l'application l'efface à la déconnexion, à la suppression du compte et à toute modification de passkey. Mais ce n'est pas l'identité elle-même ; c'est une boîte verrouillée dont les seules clés vivent à l'intérieur de vos authentificateurs. (Pour savoir comment cette boîte est scellée, voir comment CardanoWall stocke votre identité et comment les passkeys protègent votre coffre d'identité.)

Ces écritures sont entièrement supprimées en mode ordinateur public et lorsque vous choisissez de ne pas mémoriser l'appareil.

Que met-on dans sessionStorage ?

Uniquement des métadonnées d'enrôlement non secrètes — jamais de matériel de clé.

Pendant la création d'une identité, l'application recopie les métadonnées d'enrôlement des passkeys dans sessionStorage afin qu'un rechargement accidentel en pleine configuration n'efface pas l'état visible. Ces métadonnées sont non secrètes par construction : identifiants de credential, clés publiques, transports, indicateurs de type d'appareil et de sauvegarde, et autres faits dont un attaquant ne tire rien.

Ce qui est explicitement tenu à l'écart de sessionStorage :

  • les graines d'identité ;
  • les clés privées dérivées ;
  • les sorties de la fonction pseudo-aléatoire (PRF) de WebAuthn — les secrets qu'un passkey renvoie pour déverrouiller le coffre ;
  • le texte en clair du coffre ;
  • le contenu scellé déchiffré.

La règle est simple. La continuité de l'interface peut persister à travers un rechargement ; les secrets d'identité, non.

Qu'est-ce qui n'a tout simplement pas sa place dans le stockage du navigateur ?

Le matériel d'identité en clair — dans le moindre magasin.

Voici ce qui est tenu à l'écart de localStorage, de sessionStorage, d'IndexedDB, des cookies, des journaux et de l'état applicatif ordinaire :

  • la graine d'identité ;
  • les clés privées de signature Ed25519 ;
  • les clés privées de réception X25519 ;
  • les secrets de réception hybrides post-quantiques (la graine derrière l'adresse optionnelle age1pqc...) ;
  • les sorties PRF de WebAuthn ;
  • le texte en clair du coffre ;
  • le contenu scellé déchiffré, sauf si vous l'enregistrez explicitement dans un cache local chiffré, avec un contrôle clair sur celui-ci.

Le raisonnement est le même que celui qui traverse l'ensemble de la conception : plus un secret est écrit à de nombreux endroits, plus il devient difficile de raisonner sur son effacement, et plus la surface qu'une compromission peut lire est étendue.

Qu'est-ce que le mode ordinateur public ?

C'est le mode appareil partagé explicite : tant qu'il est actif, rien de lié à l'identité n'est écrit dans le stockage du navigateur.

Activez-le et l'application contourne tous les chemins de persistance liés à l'identité — pas de coffre PIN, pas de cache de coffre dans IndexedDB, pas d'épinglage de version, pas de copie d'enrôlement dans sessionStorage. Les clés déverrouillées vivent en mémoire de session uniquement : elles survivent à la navigation au sein de l'application pour cet onglet, mais disparaissent à sa fermeture ou à un rechargement. Le commutateur lui-même est volontairement en mémoire seule : persister « je suis sur un ordinateur public » serait en soi une écriture dans le stockage du navigateur, et une machine partagée devrait toujours rouvrir sur la valeur par défaut sûre, à savoir reposer la question. Utilisez-le sur un ordinateur de bibliothèque, un portable emprunté, une machine de conférence, une borne de salle de rédaction — sur tout ce que vous ne contrôlez pas.

Ce qu'il ne fait pas, c'est rendre sûr un appareil non fiable. Si la machine est déjà compromise pendant que vous saisissez une graine ou déverrouillez une identité, elle peut toujours observer des secrets en mémoire. Le mode réduit ce qui subsiste après votre départ ; il ne neutralise pas un logiciel malveillant local actif. Le mode ordinateur public couvre l'ensemble du déroulé.

Que signifie la mise à zéro en JavaScript ?

Cela signifie écraser les tableaux d'octets secrets — les remplir de zéros — dès que l'application en a terminé avec eux.

CardanoWall met à zéro ses tampons de clé Uint8Array lorsqu'une identité est verrouillée ou que vous vous déconnectez, plutôt que d'attendre en espérant que le ramasse-miettes les récupère. C'est une bonne hygiène et cela vaut la peine d'être fait.

Mais JavaScript n'est pas un environnement durci pour la manipulation de secrets, et l'honnêteté impose de le dire. Les chaînes de caractères sont immuables : un secret qui est un jour devenu une chaîne ne peut pas être effacé sur place. Le moment où survient le ramasse-miettes échappe au contrôle de l'application. Les moteurs peuvent copier la mémoire en interne. Les outils de développement, les extensions et une origine compromise modifient entièrement le modèle de risque.

La mise à zéro est donc ici une mesure faite au mieux des possibilités, et non un effacement garanti. Elle réduit véritablement la fenêtre pendant laquelle une copie résiduelle subsiste ; elle ne promet pas que les octets aient disparu partout.

Et si la page est compromise alors qu'elle est déverrouillée ?

Alors l'identité est réellement en danger — c'est la frontière la plus difficile de toute cryptographie en navigateur.

Une extension de navigateur malveillante ayant accès au contenu de la page, un appareil compromis ou une faille sérieuse de cross-site scripting (XSS) s'exécutant pendant une session déverrouillée peuvent être en mesure de lire des secrets en mémoire, ou de faire signer ou déchiffrer à l'application des choses que vous n'aviez pas voulues. Aucune application web ne peut éliminer totalement ce risque : du code qui arrive par le réseau et manipule ensuite des clés est exposé à tout ce qui tourne par ailleurs au sein de cette même origine.

CardanoWall s'appuie sur la défense en profondeur pour réduire la fenêtre : une Content Security Policy stricte qui confine les scripts à l'origine propre de l'application — sans aucun script en ligne, sans eval, et sans aucun script tiers chargé — à quoi s'ajoutent des en-têtes de sécurité apposés sur chaque réponse en périphérie, une surface de secrets délibérément réduite, l'absence de toute persistance en clair, et un déverrouillage comme un déchiffrement déclenchés uniquement par une action explicite de l'utilisateur — jamais automatiquement à la prise de focus de l'onglet. Tout cela réduit la probabilité et le rayon d'impact. Cela ne rend pas inoffensif un script malveillant à l'intérieur d'une origine déverrouillée ; cela demeure la menace au plus fort impact que le modèle navigateur accepte.

Pour vos identités les plus sensibles, la bonne réponse consiste à sortir le matériel de clé de la surface web partagée. Conservez-les sur un appareil dédié et de confiance, et privilégiez un déroulé où le secret ne touche jamais un navigateur — la CLI en automatisation, ou CardanoWall Desktop, qui garde vos clés dans un cœur Rust local plutôt que dans une origine web. (Pour le principe plus général, voir pourquoi les clés ne quittent jamais l'appareil.)

Que devriez-vous concrètement faire ?

Utilisez le modèle navigateur de façon réfléchie, et ajustez les précautions à la sensibilité du travail.

Pour un usage quotidien :

  • enregistrez votre graine d'identité en lieu sûr — c'est la vraie sauvegarde ;
  • ajoutez un passkey pour le déverrouillage quotidien ;
  • verrouillez ou déconnectez-vous quand vous avez terminé ;
  • n'utilisez « mémoriser cet appareil » que sur des machines de confiance ;
  • maintenez votre navigateur et votre système d'exploitation à jour ;
  • évitez les extensions de navigateur à haut risque ;
  • activez le mode ordinateur public sur tout appareil partagé.

Pour un travail sensible, ajoutez :

  • un profil de navigateur dédié ou, mieux, un appareil dédié ;
  • aucun déverrouillage sur des machines empruntées ;
  • une clé de sécurité matérielle comme facteur de déverrouillage ;
  • une séparation entre les identités à haut risque et les identités ordinaires ;
  • de la prudence avec les records scellés — un destinataire capable de déchiffrer peut aussi divulguer le texte en clair par la suite.

En bref

L'application web de CardanoWall a besoin de clés privées tant qu'une identité est déverrouillée ; elle les garde donc en mémoire de session plutôt que dans un stockage persistant. IndexedDB ne met en cache que le texte chiffré du coffre ; sessionStorage ne contient que des métadonnées de configuration non secrètes. La graine d'identité et les clés privées ne sont jamais écrites comme des données de navigateur ordinaires.

Le modèle de coffre hébergé et le modèle de stockage navigateur se renforcent mutuellement : le serveur détient un texte chiffré qu'il ne peut pas déchiffrer, et le navigateur s'efforce de ne pas laisser la graine derrière lui. Aucune de ces deux affirmations n'est une garantie contre un appareil déjà compromis — et être clair sur cette limite fait partie du sérieux qu'on lui accorde. Pour la vue d'ensemble de ce que le service peut et ne peut pas observer, voir ce que CardanoWall peut voir.

securitybrowser-securityidentity