Sicurezza
Un modello di fiducia che si spiega si può verificare; uno che si nasconde, no. Ecco cosa fa SecureChat, e anche cosa non fa.
In breve
- I messaggi sono cifrati end-to-end tra il tuo telefono e il server dell’azienda. Noi trasportiamo solo testo cifrato.
- Non generiamo né vediamo mai le chiavi private: la tua nasce sul tuo telefono; quella dell’azienda, sulla sua infrastruttura.
- Verifichiamo le aziende e firmiamo la loro chiave pubblica; l’app ti avvisa se quella chiave cambia.
- La cifratura finisce nel backend dell’azienda: quello che fa con il testo decifrato è fuori dal nostro controllo.
- La versione attuale del protocollo non offre la forward secrecy.
- Siamo l’elenco delle chiavi di entrambe le parti: senza la protezione aggiuntiva del link, un operatore malintenzionato attivo (noi) potrebbe sostituire una chiave al primo contatto.
Come viene cifrato un messaggio (busta v1)
Usiamo libsodium, una libreria crittografica verificata e ampiamente diffusa. Questi sono i componenti della busta v1 (sc1):
| Componente | Costruzione |
|---|---|
| Identità (il tuo dispositivo e l’azienda) | Coppia di chiavi X25519 |
| Chiave della conversazione | 32 byte casuali generati dal tuo telefono quando usi l’invito. Se la generassimo noi, la conosceremmo. |
| Distribuzione di quella chiave | Viene sigillata separatamente (crypto_box_seal) per la tua chiave pubblica e per quella dell’azienda. Noi conserviamo solo le due buste sigillate. |
| Cifratura di ogni messaggio | XChaCha20-Poly1305 con nonce casuale di 24 byte |
| Dati associati | Ogni messaggio resta legato alla sua conversazione, al mittente, al suo identificativo e alla versione della chiave. Un server non può spostarlo in un’altra conversazione, duplicarlo con un altro identificativo né far passare un tuo messaggio per uno dell’azienda. |
| Riempimento | Fino a multipli di 256 byte, per nascondere la lunghezza esatta |
| Firma della chiave dell’azienda | Ed25519, con la chiave di piattaforma |
| Firma della rotazione della chiave | Ed25519, con la chiave di firma dell’azienda stessa (più sotto) |
| Impronte | BLAKE2b-256 con separazione di dominio |
Allegati cifrati
Foto e documenti vengono cifrati sul dispositivo che li invia (il tuo telefono o il server dell’azienda), proprio come il testo:
- Ogni file ha una propria chiave di 32 byte, casuale e diversa da quella della conversazione.
- Viene cifrato in blocchi da 64 KiB con XChaCha20-Poly1305. Ogni blocco è autenticato insieme all’identificativo dell’allegato, alla sua posizione e all’indicazione se è l’ultimo: riordinare, troncare o aggiungere blocchi fa fallire la decifratura.
- La chiave del file, il nome, il tipo, la dimensione e l’impronta (BLAKE2b) viaggiano dentro un normale messaggio cifrato. Alla fine l’app controlla l’impronta; se qualcosa non torna, mostra “Impossibile decifrare questo allegato” e mai un file a metà.
- Noi conserviamo solo byte opachi e un identificativo. Vediamo la dimensione del file cifrato, praticamente uguale a quella dell’originale: gli allegati non vengono riempiti come i messaggi. Solo i due capi della conversazione possono caricarlo e scaricarlo, con link temporanei validi 5 minuti.
- Massimo 25 MB per file. Non generiamo miniature (non possiamo: non vediamo il contenuto); l’app crea l’anteprima dopo la decifratura.
Cosa protegge
- Una fuga di dati dal nostro database o dai nostri backup: contengono solo testo cifrato.
- Un dipendente curioso con accesso ai server.
- Un attaccante passivo sulla rete, o chiunque intercetti il traffico.
- Le notifiche push: non contengono il messaggio, quindi né Apple né Google lo vedono.
- La manomissione dei messaggi in transito o sui nostri server: la decifratura fallisce invece di mostrare un testo alterato.
Cosa non protegge
- L’altro capo è il backend dell’azienda. È lì che il messaggio viene decifrato. Se l’azienda lo inoltra in chiaro a un helpdesk o CRM nel cloud, quel fornitore può vederlo. Se lavori in un settore regolamentato, chiedi all’azienda dove finisce il testo.
- Noi, agendo attivamente. La tua app riceve la chiave dell’azienda dal nostro server, e anche l’azienda riceve la tua da noi. Un operatore malintenzionato potrebbe sostituire l’una o l’altra. L’app fissa la chiave dell’azienda al primo contatto e ti avvisa se cambia, ma questo non protegge proprio quel primo contatto. L’impronta del link (più sotto) chiude questa falla quando l’invito arriva tramite un link generato con l’SDK.
- Un dispositivo compromesso. Se qualcuno controlla il tuo telefono o il server dell’azienda, può leggere lì i messaggi.
- I metadati. Li spieghiamo più sotto.
Chiave di piattaforma e verifica delle aziende
Prima che un’azienda possa invitare, verifichiamo la sua esistenza legale, che controlli il suo dominio (record DNS) e il numero WhatsApp da cui invita. Poi firmiamo la sua chiave pubblica con la nostra chiave di piattaforma Ed25519. L’app verifica questa firma e mostra il badge Azienda verificata.
Chiave pubblica di piattaforma (Ed25519, base64url):
qxh_sOak_wQVqZifJjDcoy-TeWIF3NADjqsjta0GPlw
Ciò che viene firmato è esattamente SecureChat|v1|company-key|<companyId>|<keyVersion>|<chiave pubblica>. Questo concentra il rischio su di noi: se qualcuno rubasse la chiave di piattaforma, potrebbe spacciarsi per un marchio. Per questo esiste anche il controllo del link.
L’azienda genera la propria coppia di chiavi sulla sua infrastruttura con il nostro SDK (npx @securechat/sdk keygen) e ci carica solo la chiave pubblica. Il portale non offre di generarla nel browser: se la chiave privata passasse dai nostri server, la promessa non sarebbe più verificabile.
Aziende non verificate e Modalità prova
Perché un’azienda possa provare la sua integrazione mentre la esaminiamo, può creare inviti di prova. La sua chiave non è firmata come verificata, quindi chiunque potrebbe registrarsi come “Banca X” e usarli per spacciarsi per un marchio. Per questo:
- L’app apre un invito di prova solo se hai attivato la Modalità prova in Impostazioni → Diagnostica. È disattivata per impostazione predefinita: un cliente normale non finisce mai per errore in una conversazione di prova, anche se riceve il link. Non attivarla perché qualcuno te lo chiede: un’azienda vera non ne ha bisogno per parlarti.
- Quelle conversazioni mostrano sempre la fascia “Azienda non verificata · ambiente di prova” e mai il badge di azienda verificata.
- Hanno limiti rigidi: 5 conversazioni attive per azienda, 200 messaggi dell’azienda al giorno e inviti di massimo 24 ore. Quando verifichiamo l’azienda, le sue conversazioni di prova vengono chiuse.
La cifratura è la stessa di una conversazione normale. Cambia la garanzia di identità: in una conversazione di prova non abbiamo verificato chi è l’azienda.
L’impronta nel link di invito
Quando l’azienda crea l’invito con l’SDK, aggiunge al link un frammento #s=…&fp=…. Il browser non invia il frammento al server, quindi noi non lo vediamo, ma il link viaggia su WhatsApp, un canale che non controlliamo. Quando usi l’invito:
- L’app controlla che la chiave dell’azienda che le forniamo abbia l’impronta
fpdel link. - L’app lega la propria chiave al segreto
scon un MAC, e l’azienda lo verifica.
Se sostituissimo una delle due chiavi, uno dei due capi se ne accorgerebbe. Limiti: copre solo l’uso tramite link, non il codice breve digitato, e gli inviti creati a mano dal portale non contengono quel segreto.
Rotazione della chiave firmata dall’azienda
Oltre alla chiave di cifratura, l’azienda genera con l’SDK una chiave di firma Ed25519 che resta anch’essa sulla sua infrastruttura; ci carica solo quella pubblica. L’app la fissa al primo contatto, insieme a quella di cifratura. Quando l’azienda ruota la sua chiave di cifratura, firma il cambio con quella chiave di firma: SecureChat|v1|company-key-rotation|<companyId>|<versione precedente>|<chiave precedente>|<nuova versione>|<nuova chiave>. Verifichiamo la firma prima di accettare la nuova chiave, e l’app la verifica di nuovo.
- Rotazione firmata dalla chiave fissata: avviso discreto (“l’azienda ha rinnovato la sua chiave di sicurezza; il cambio è firmato dall’azienda stessa”).
- Senza firma, o firmata con un’altra chiave: avviso in evidenza. Conviene confermare con l’azienda tramite un altro canale prima di proseguire. Le aziende che non hanno caricato una chiave di firma ruotano sempre così.
Perché conta: con la sola nostra firma di piattaforma, una rotazione legittima e una sostituzione fatta da noi sembrerebbero uguali. Con la firma dell’azienda, spacciarsi per un’azienda che hai già fissato richiede la sua chiave di firma, che non passa mai da noi. La firma di piattaforma resta obbligatoria in entrambi i casi. Per ora la chiave di firma non ruota: cambiarla viene trattato come una rotazione non firmata.
Niente forward secrecy nella v1
Ogni conversazione usa una chiave stabile. Se in futuro la tua chiave privata o quella dell’azienda venisse divulgata, insieme ai messaggi cifrati conservati, si potrebbero decifrare anche i messaggi precedenti di quella conversazione. Protocolli come Signal rinnovano le chiavi a ogni messaggio per evitarlo; l’abbiamo lasciato fuori deliberatamente dalla prima versione del protocollo ed è nella nostra roadmap.
Metadati
Anche se non vediamo il contenuto, vediamo chi parla con quale azienda, quando e con che frequenza, la dimensione approssimativa di ogni messaggio (arrotondata a 256 byte), la dimensione e la data di ogni allegato, gli indirizzi IP e i dati del dispositivo. Bastano per dedurre parecchio, ed è per questo che lo dichiariamo nell’informativa sulla privacy.
La cronologia è legata al tuo dispositivo: se lo perdi, recuperi ogni conversazione con un nuovo invito dell’azienda, che sigilla di nuovo la chiave per il tuo nuovo dispositivo.
Segnalare una vulnerabilità
Scrivici a soporte@securechat-app.com con oggetto “Sicurezza”. Ti chiediamo un tempo ragionevole per correggerla prima di renderla pubblica.