Tutti gli articoli

9 min di lettura

Dove CardanoWall custodisce le tue chiavi nel browser

Nel browser, CardanoWall tiene le chiavi sbloccate nella memoria di sessione e scrive in IndexedDB soltanto il testo cifrato del vault — mai Identity Seed o chiavi private in chiaro.

Quando sblocchi CardanoWall nel browser, il seed sbloccato e le chiavi private da esso derivate vivono nella memoria di sessione — la normale memoria dell'applicazione, che svanisce quando blocchi, esci o chiudi la scheda. Lo storage persistente del browser (IndexedDB, sessionStorage) conserva soltanto il testo cifrato del vault e metadati non segreti. Identity Seed e chiavi private derivate in chiaro non vi vengono mai scritti.

È proprio in questa distinzione che sta tutto il senso. Il browser deve gestire del materiale di chiave per firmare e decifrare in locale — è così che la crittografia funziona, punto. La domanda sulla sicurezza non è mai «il browser può toccare le chiavi?». Deve poterlo fare. La domanda è dove vivono quelle chiavi e cosa finisce scritto su disco. Il modello web di CardanoWall è costruito perché ciò che sopravvive a un ricaricamento sia testo cifrato, non segreti.

Cosa serve al browser mentre un'identità è sbloccata?

Gli serve il materiale di chiave privata per il lavoro che stai effettivamente facendo — e niente che duri più della sessione stessa.

Dopo che hai sbloccato un'identità, l'app potrebbe dover:

  • firmare un record Label 309;
  • decifrare un record sigillato indirizzato a te;
  • decifrare a tentativi i record sigillati in arrivo per individuare quelli destinati alla tua Inbox;
  • ricifrare il vault dopo che aggiungi o rimuovi una passkey;
  • mostrare il seed quando chiedi esplicitamente di vederlo;
  • ricostruire le cache cifrate locali.

Niente di tutto questo è possibile con le sole chiavi pubbliche. Ogni operazione ha bisogno di materiale privato derivato dal tuo Identity Seed. Il design tiene quel materiale nella memoria di sessione e lo cancella al blocco o all'uscita — per quanto possibile, per ragioni che vedremo più avanti.

Cos'è qui la memoria di sessione?

La memoria di sessione è la memoria temporanea dell'applicazione, interna al processo, che l'app scarta quando la sessione di sblocco termina.

Nell'app browser di CardanoWall, il seed attivo e le chiavi da esso derivate sono custoditi al di fuori del normale stato dell'interfaccia, in mappe di memoria interne. Lo stato reattivo dell'interfaccia conserva soltanto fatti non segreti: quale identità è sbloccata, quando è stata sbloccata, quali metadati di registrazione delle passkey sono a schermo durante la configurazione. I byte segreti non entrano mai in quello stato reattivo.

Questa separazione è importante perché il normale stato dell'interfaccia è la parte di un'app più esposta a ispezione, serializzazione, persistenza o passaggi accidentali a un componente che la registra in un log. Il materiale segreto merita una superficie più piccola e deliberatamente enumerata. Ogni punto dell'app che può restituire byte segreti — la closure di firma, le chiavi di decifratura, la via d'uscita per mostrare il seed, il percorso di ricostruzione del vault — è elencato in un solo file, e ciascuno restituisce una copia difensiva anziché il buffer attivo.

Il browser continua a custodire i segreti mentre sei sbloccato. Semplicemente, non li tratta come normali dati dell'app.

Cosa viene scritto in IndexedDB?

Il testo cifrato del vault — gli stessi byte che il server conserva, non i seed che vi sono contenuti.

IndexedDB serve come cache locale del tuo vault dell'identità cifrato: una riga per account, che contiene esattamente il testo cifrato con age che il server conserva. Tenerlo in cache permette all'app di reidratarsi dopo un ricaricamento con un solo tocco di passkey, senza una nuova chiamata di rete per recuperare di nuovo il vault.

Un attaccante che si limiti a leggere quel database locale vede byte cifrati del vault indirizzati alle tue passkey — non seed in chiaro. La cache resta comunque un dato di servizio sensibile, e l'app la cancella all'uscita, alla cancellazione dell'account e a ogni modifica delle passkey. Ma non è l'identità in sé: è una scatola chiusa le cui uniche chiavi vivono dentro i tuoi autenticatori. (Per come quella scatola viene sigillata, vedi come CardanoWall conserva la tua identità e come le passkey proteggono il vault della tua identità.)

Queste scritture sono soppresse del tutto in modalità computer pubblico e quando scegli di non ricordare il dispositivo.

Cosa finisce in sessionStorage?

Soltanto metadati di registrazione non segreti — mai materiale di chiave.

Durante la creazione di un'identità, l'app rispecchia i metadati di registrazione delle passkey in sessionStorage, così che un ricaricamento accidentale a metà configurazione non azzeri lo stato visibile. Quei metadati sono non segreti per costruzione: ID delle credenziali, chiavi pubbliche, transport, flag di tipo di dispositivo e di backup, e fatti simili da cui un attaccante non ricava nulla.

Ciò che è esplicitamente tenuto fuori da sessionStorage:

  • gli Identity Seed;
  • le chiavi private derivate;
  • gli output WebAuthn PRF (pseudo-random function) — i segreti che una passkey restituisce per sbloccare il vault;
  • il testo in chiaro del vault;
  • il contenuto sigillato decifrato.

Il confine è semplice. La continuità dell'interfaccia può sopravvivere a un ricaricamento; i segreti dell'identità no.

Cosa non deve mai stare nello storage del browser?

Il materiale dell'identità in chiaro — in qualsiasi store.

Questi elementi sono tenuti fuori da localStorage, sessionStorage, IndexedDB, cookie, log e dal normale stato dell'app:

  • l'Identity Seed;
  • le chiavi private di firma Ed25519;
  • le chiavi private di ricezione X25519;
  • i segreti di ricezione ibridi post-quantum (il seed dietro l'indirizzo opzionale age1pqc...);
  • gli output WebAuthn PRF;
  • il testo in chiaro del vault;
  • il contenuto sigillato decifrato, a meno che tu non lo salvi esplicitamente in una cache locale cifrata con un controllo chiaro su di esso.

Il ragionamento è lo stesso che attraversa l'intero design: più sono i punti in cui un segreto viene scritto, più diventa difficile ragionare sulla sua cancellazione e più grande è la superficie che una compromissione può leggere.

Cos'è la modalità computer pubblico?

È la modalità esplicita per dispositivi condivisi: finché è attiva, nello storage del browser non viene scritto nulla che riguardi l'identità.

Attivala e l'app salta ogni percorso di persistenza legato all'identità — niente PIN vault, niente cache del vault in IndexedDB, niente version pin, niente mirror della registrazione in sessionStorage. Le chiavi sbloccate vivono soltanto nella memoria di sessione: sopravvivono alla navigazione interna all'app per quella scheda, ma muoiono alla chiusura della scheda o al ricaricamento. L'interruttore stesso è solo in memoria, e di proposito: rendere persistente «sono su un computer pubblico» sarebbe a sua volta una scrittura nello storage del browser, e una macchina condivisa dovrebbe sempre riaprirsi nell'impostazione predefinita sicura, cioè chiedendo di nuovo. Usala sul computer di una biblioteca, su un portatile prestato, su una postazione a una conferenza, sul chiosco di una redazione — su qualunque cosa tu non controlli.

Ciò che non fa è rendere sicuro un dispositivo non fidato. Se la macchina è già compromessa mentre digiti un seed o sblocchi un'identità, può comunque osservare i segreti in memoria. La modalità riduce ciò che resta dopo che te ne vai; non sconfigge un malware locale attivo. La modalità computer pubblico descrive l'intero flusso di lavoro.

Cosa significa azzeramento in JavaScript?

Significa sovrascrivere gli array di byte segreti — riempiendoli di zeri — non appena l'app ha finito di usarli.

CardanoWall azzera i suoi buffer di chiavi Uint8Array quando un'identità viene bloccata o quando esci, anziché aspettare e sperare che il garbage collector li recuperi. È buona igiene e vale la pena farlo.

Ma JavaScript non è un ambiente irrobustito per la gestione dei segreti, ed è onesto dirlo. Le stringhe sono immutabili, quindi un segreto che a un certo punto sia diventato una stringa non può essere cancellato sul posto. La tempistica del garbage collection non è sotto il controllo dell'app. Gli engine possono copiare la memoria internamente. Strumenti per sviluppatori, estensioni e un'origine compromessa cambiano del tutto il modello di rischio.

Quindi l'azzeramento, qui, è una misura per quanto possibile, non una cancellazione garantita. Restringe in modo significativo la finestra in cui una copia vagante può sopravvivere; non promette che i byte siano spariti ovunque.

E se la pagina viene compromessa mentre è sbloccata?

Allora l'identità è davvero a rischio — è il confine più difficile di qualunque crittografia basata sul browser.

Un'estensione del browser malevola con accesso al contenuto della pagina, un dispositivo compromesso o un grave bug di cross-site-scripting (XSS) in esecuzione durante una sessione sbloccata potrebbero leggere i segreti dalla memoria, oppure far firmare o decifrare all'app cose che non intendevi. Nessuna web app può eliminare del tutto questo rischio: codice che arriva dalla rete e poi gestisce chiavi è esposto a qualunque altra cosa giri nella stessa origine.

CardanoWall si appoggia alla difesa in profondità per restringere la finestra: una Content Security Policy rigorosa che confina gli script all'origine dell'app stessa — senza script inline, senza eval e senza alcun script di terze parti caricato — più header di sicurezza apposti su ogni risposta a livello edge, una superficie di segreti deliberatamente piccola, nessuna persistenza in chiaro, e sblocco e decifratura solo su azione esplicita dell'utente — mai automaticamente al focus della scheda. Queste misure riducono le probabilità e il raggio d'impatto. Non rendono innocuo uno script malevolo dentro un'origine sbloccata; questa resta la minaccia a più alto impatto che il modello browser accetta.

Per le tue identità più sensibili, la risposta giusta è spostare il materiale di chiave fuori dalla superficie web condivisa. Tienile su un dispositivo dedicato e fidato, e preferisci un flusso di lavoro in cui il segreto non tocchi mai un browser — la CLI in automazione, oppure CardanoWall Desktop, che custodisce le tue chiavi in un core locale in Rust anziché in un'origine web. (Per il principio più generale, vedi perché le chiavi non lasciano mai il dispositivo.)

Cosa dovresti fare in concreto?

Usa il modello browser in modo consapevole e adatta le precauzioni alla sensibilità del lavoro.

Per l'uso quotidiano:

  • salva il tuo Identity Seed in un luogo sicuro — è il vero backup;
  • aggiungi una passkey per lo sblocco quotidiano;
  • blocca o esci quando hai finito;
  • usa «ricorda questo dispositivo» solo su macchine di cui ti fidi;
  • tieni aggiornati browser e sistema operativo;
  • evita le estensioni del browser ad alto rischio;
  • attiva la modalità computer pubblico su qualsiasi dispositivo condiviso.

Per il lavoro sensibile, aggiungi:

  • un profilo del browser dedicato o, meglio, un dispositivo dedicato;
  • nessuno sblocco su macchine prestate;
  • una chiave di sicurezza hardware come fattore di sblocco;
  • la separazione tra identità ad alto rischio e identità ordinarie;
  • attenzione con i record sigillati — un destinatario in grado di decifrare può anche divulgare il testo in chiaro in seguito.

In breve

L'app browser di CardanoWall ha bisogno delle chiavi private mentre un'identità è sbloccata, perciò le tiene nella memoria di sessione anziché nello storage persistente. IndexedDB mette in cache soltanto il testo cifrato del vault; sessionStorage conserva soltanto metadati di configurazione non segreti. L'Identity Seed e le chiavi private non vengono mai scritti come normali dati del browser.

Il modello del vault ospitato e il modello dello storage del browser si rafforzano a vicenda: il server conserva un testo cifrato che non può decifrare, e il browser fa del suo meglio per non lasciarsi dietro il seed. Nessuna delle due affermazioni è una garanzia contro un dispositivo già compromesso — ed essere chiari su questo limite è parte del prenderlo sul serio. Per il quadro completo di ciò che il servizio può e non può osservare, vedi cosa può vedere CardanoWall.

securitybrowser-securityidentity