Sicurezza · Approfondimento

Il ciclo di vita crittografico completo

Una descrizione precisa di cosa succede ai tuoi dati in ogni fase, con primitive, parametri e confini di fiducia nel dettaglio. Ogni fase si apre con un riassunto in parole semplici, così puoi leggere al livello di dettaglio che preferisci.

Fase 01 · Cifratura

Il tuo segreto viene sigillato sul tuo dispositivo

In parole semplici: la cifratura avviene nel tuo browser, prima che venga caricato qualsiasi dato. Quello che riceviamo è già illeggibile.

Quando premi Cifra, il browser genera una nuova chiave di contenuto a 256 bit dal WebCrypto CSPRNG e cifra il contenuto con AES-256-GCM. GCM è autenticato: ogni blocco porta un tag a 128 bit, quindi qualsiasi manomissione successiva viene rilevata invece di essere decifrata senza avvisi.

Testo e file vengono trattati allo stesso modo: entrambi diventano un unico blob binario opaco, portato con il padding a una dimensione standard, così una password breve e un file piccolo sembrano uguali. Il testo in chiaro non tocca mai la rete e non lascia mai la memoria della scheda.

CifrarioAES-256-GCM, blocchi da 64 KiB
Chiave di contenuto256 bit, nuova per ogni segreto
Nonceprefisso casuale di 7 byte + contatore
Tag di autenticazione128 bit per blocco
PaddingPadmé, minimo 64 KiB

Fase 02 · Custodia della chiave

La chiave è nascosta nel link, non sui nostri server

In parole semplici: la parte del link dopo il # contiene la chiave, e i browser non inviano mai quella parte a nessun server.

Il tuo link contiene un seed casuale a 256 bit nel frammento dell'URL, cioè tutto ciò che segue il #. Secondo la specifica degli URL, il browser rimuove il frammento e non lo include mai nella richiesta inviata ai nostri server. Da quel seed il browser ricava, con HKDF, un valore di ricerca per trovare il segreto e la chiave che sblocca la chiave di contenuto. Il server vede sempre e solo un hash del valore di ricerca.

Il browser del destinatario legge il seed dal frammento ed esegue la stessa derivazione in locale. Ecco cosa significa qui «zero-knowledge»: possedere solo il testo cifrato è inutile senza il link.

Posizione della chiaveframmento dell'URL #
Inviata al server?mai
Seed32 byte casuali, base64url
DerivazioneHKDF-SHA-256
Il server conservasolo SHA-256(lookup)

Fase 03 · Passphrase facoltativa

Un secondo lucchetto che solo le persone conoscono

In parole semplici: aggiungi una passphrase e nemmeno chi ha il link completo potrà aprire il segreto senza di essa.

Se imposti una passphrase, viene rafforzata con Argon2id, una funzione di derivazione della chiave memory-hard, e combinata con il seed nella chiave che protegge la chiave di contenuto. La passphrase in sé non viene mai trasmessa né conservata: la conoscete solo tu e il destinatario. I tentativi errati vengono ripetuti nel browser del destinatario sui dati che ha già, quindi il server non può contarli.

L'uso intensivo di memoria rende costosi i tentativi offline su larga scala, anche con GPU e ASIC. Condividi la passphrase su un canale diverso da quello del link, così i due fattori non si trovano mai nello stesso posto. Il modulo Argon2 viene scaricato a ogni creazione e apertura, così la rete non può capire quali segreti ne usano una.

KDFArgon2id
Saltcasuale a 128 bit
WrappingAES-256-GCM, IV a 96 bit

Fase 04 · Trasferimento & archiviazione

Dal tuo dispositivo esce solo testo cifrato

In parole semplici: conserviamo una scatola chiusa e un orario di scadenza. Nient'altro: niente testo in chiaro, niente chiave, nessuna traccia di te.

Il blob viene caricato tramite TLS e conservato a riposo come testo cifrato, insieme a credenziali sottoposte a hash, alla sua durata e a un orario di scadenza arrotondato. Di proposito non conserviamo l'identità del mittente, il destinatario, log degli IP, l'orario di creazione o lo storico degli accessi. Non esiste un sistema di account che colleghi un segreto a una persona. Il rate limiting lavora su un HMAC dell'indirizzo con un salt che ruota, quindi nulla di ciò che precede una rotazione può essere collegato a ciò che la segue.

Poiché l'oggetto conservato non ha senso senza il seed nel frammento, la compromissione del server o un ordine giudiziario producono solo byte opachi e hash da cui non si può risalire a nulla.

In transitoTLS
A riposotesto cifrato + chiavi sottoposte a hash + scadenza
Lognessuno per singolo segreto

Fase 05 · Recupero & distruzione

Vince la prima lettura, poi viene cancellato

In parole semplici: aprire un link monouso consegna la scatola una sola volta ed elimina la copia sul server. Oppure distruggilo tu, quando vuoi.

Al caricamento della pagina di apertura non viene recuperato nulla: la richiesta parte solo dopo un vero clic o la pressione di un tasto, quindi gli scanner di link e le anteprime delle chat non possono consumare un segreto. Per un segreto monouso il server rivendica la riga con un unico aggiornamento condizionale (vince esattamente una richiesta) e da quel momento il segreto è considerato consumato. Lo stesso browser può riscaricarlo per 15 minuti se la connessione cade; nessun altro può farlo, e una rivendicazione non confermata viene distrutta, mai annullata. I segreti a tempo sono una semplice lettura fino alla scadenza.

Ogni segreto ha anche un link di distruzione privato. Aprirlo di per sé non distrugge nulla; confermando, il testo cifrato viene cancellato subito, prima che qualsiasi destinatario possa leggerlo.

Monousorivendicazione atomica, poi distruzione
Finestra di riscaricamento15 min, solo lo stesso client
Scadenzada 15 min a 14 giorni
Controllo del proprietariolink di distruzione

Modello di minaccia

Cosa shhnote può e non può vedere

La versione onesta. Ecco esattamente dove si trova il confine di fiducia.

Non lascia mai il tuo dispositivo

Cosa non possiamo vedere

Il tuo testo in chiaro · la chiave di contenuto e il seed · la tua passphrase · se è stata impostata una passphrase · chi ha creato o aperto un segreto · quando è stato creato · log di accesso a livello di IP. Nulla di tutto questo viene trasmesso o conservato.

Conservato sui nostri server

Cosa conserviamo

Un blob cifrato che non possiamo aprire · la sua classe di dimensione dopo il padding · hash unidirezionali dei valori che il tuo browser usa per trovarlo o distruggerlo · se è monouso o a tempo · un orario di scadenza arrotondato. Tutto inutile senza il seed contenuto nel tuo link.

Da sapere

Le avvertenze oneste

Chiunque abbia il link completo (e la passphrase, se impostata) può leggere un segreto monouso: tratta il link come il segreto stesso. Dopo che un segreto è stato mostrato, la pagina sovrascrive ciò che può quando la lasci, ma JavaScript non può garantirlo; chiudi la scheda quando hai finito. Un browser controllato da automazioni che simulano input reali può aprire un segreto monouso come farebbe una persona: il destinatario allora non trova nulla, ed è l'esito onesto. Eliminare un segreto rimuove il record; residui cifrati possono restare nei journal, nello spazio libero su disco o nei backup finché non vengono sovrascritti, come testo cifrato senza chiave. I segreti di grandi dimensioni conservati fuori dal database portano con sé l'orario in cui il file è stato scritto. E come per qualsiasi web app, ti fidi del codice inviato al tuo browser: per questo shhnote è open source e si può ospitare in proprio.

Specifica crittografica

Tutte le primitive, in un unico posto

Cifratura

AES-256-GCM

Cifratura simmetrica autenticata in blocchi da 64 KiB. Una chiave a 256 bit più un tag di integrità per blocco, quindi manomissioni o troncamenti vengono rilevati, non solo resi illeggibili.

Derivazione della chiave

HKDF · Argon2id

Chiavi e identificatori derivano dal seed tramite HKDF-SHA-256. Le passphrase facoltative vengono rafforzate con una KDF memory-hard, che rende il brute force offline lento e costoso anche su hardware dedicato.

Casualità

WebCrypto CSPRNG

Seed, chiavi, salt e nonce provengono dal generatore crittograficamente sicuro del browser. Mai Math.random(), mai prevedibili.

Custodia della chiave

Frammento dell'URL #

Il seed viaggia dopo il # nel tuo link. I browser non trasmettono mai il frammento, quindi non raggiunge mai i nostri server.

In transito

TLS

Dal tuo dispositivo esce solo testo cifrato, trasportato su TLS moderno. Quello che riceviamo è un blob opaco che non possiamo aprire.

A riposo

Testo cifrato + hash

Conserviamo un blob cifrato, hash unidirezionali delle sue credenziali e una scadenza arrotondata: niente testo in chiaro, niente chiavi, nessun metadato su mittente o destinatario.

FAQ tecniche

Per chi tiene alla sicurezza

Come viene garantito l'uso singolo contro le richieste concorrenti?

L'apertura esegue un unico aggiornamento condizionale che porta la riga da «active» a «claimed». Due richieste simultanee non possono andare entrambe a buon fine: la seconda trova un record già rivendicato e riceve la stessa risposta «nessun segreto trovato» di chiunque altro. La rivendicazione non viene mai annullata: se il download va perso, chi possiede il token di rivendicazione lo riscarica entro la finestra prevista, altrimenti il segreto viene distrutto senza essere letto.

Perché il frammento dell'URL e non un parametro di query?

I parametri di query vengono inviati al server e finiscono nei log di accesso, nei proxy e negli strumenti di analisi. Il frammento (dopo il #) è definito dalla specifica degli URL come lato client: il browser non lo inserisce mai nella richiesta HTTP. Questa proprietà è l'intera base del modello zero-knowledge. Dopo l'apertura, la pagina rimuove anche il frammento dalla barra degli indirizzi e dalla cronologia.

Cosa impedisce agli scanner di link di consumare in anticipo i segreti monouso?

La pagina di visualizzazione è lo stesso documento statico per ogni segreto e non recupera nulla al caricamento. La richiesta parte solo dopo un clic o la pressione di un tasto attendibili: un click() eseguito da script o l'invio di un modulo non contano. Gli scanner automatici (sicurezza email, anteprime delle chat, antivirus) caricano sempre e solo quell'involucro statico.

Posso verificarlo o ospitarlo da me?

Sì. Tutto il codice sorgente è pubblico con licenza AGPLv3, il protocollo è descritto in una specifica con vettori di conformità con cui qualsiasi implementazione può verificarsi, e c'è una guida al self-hosting. Puoi esaminare la crittografia lato client e gestire una tua istanza, così il confine di fiducia è interamente tuo.

Viene registrato qualcosa per prevenire gli abusi?

Non conserviamo log di accesso per singolo segreto né storico degli IP. Il rate limiting usa un hash con chiave dell'indirizzo, con un salt che ruota e azzera ogni contatore a ogni rotazione. Le segnalazioni di abuso vengono contate per giorno; non resta traccia di quale segreto sia stato segnalato.

Consigli per condividere in sicurezza

  • Invia la passphrase in modo diverso dal link, per esempio il link via email e la passphrase per telefono.
  • Scegli la scadenza più breve che vada bene per te.
  • Usa un segreto monouso per password e altre informazioni che devono essere lette una sola volta.

Segnalare una vulnerabilità

Se pensi di aver trovato un problema di sicurezza in questo sito, scrivi a [email protected] e comunicacelo in privato prima di dirlo a chiunque altro. Indica cosa hai trovato e come riprodurlo.

Ci impegniamo a:

  • risponderti entro 5 giorni lavorativi;
  • tenerti aggiornato mentre lo correggiamo;
  • citarti quando pubblichiamo la correzione, se lo desideri.

Durante i test, non accedere ai dati di altre persone, non disturbare il servizio e non eseguire scansioni automatiche che lo sovraccarichino.

Vulnerabilità nel software shhnote stesso: consulta la policy di sicurezza del progetto.

Crea un segreto Vedi il codice su GitHub

Provalo: bastano dieci secondi

Scrivi qualcosa di segreto, ottieni il tuo link monouso e guardalo sparire.

Crea un segreto