Vorremmo commissionare un plugin che consenta messaggistica privata e crittografata tra gli utenti finali.
Questo plugin esiste già ed è ufficialmente supportato; consultate Discourse Encrypt (deprecated)
Al momento, esistono pochissimi spazi online per comunicazioni private, sicure e di lunga durata. Gli strumenti esistenti sono solitamente piuttosto complessi e richiedono competenze tecniche avanzate per essere utilizzati. Di conseguenza, la maggior parte delle comunicazioni “private” avviene in forma “breve” su Telegram, Skype o WhatsApp. Inoltre, questa modalità di comunicazione di massa non è adeguatamente verificabile, poiché si basa su strumenti closed source e spesso su protocolli chiusi.
Desideriamo creare una soluzione altamente utilizzabile e verificabile per la messaggistica crittografata all’interno di un plugin dedicato per Discourse.
Per raggiungere questo obiettivo, ci baseremo sui seguenti principi:
-
Costruire la soluzione utilizzando l’API Web Crypto.
-
Far sì che il server memorizzi una chiave privata crittografata e una chiave pubblica per ogni utente.
-
Far sì che il server memorizzi una chiave di conversazione crittografata per ogni partecipante alle messaggi private (crittografata utilizzando la chiave privata dell’utente finale).
-
Memorizzare tutto il contenuto Markdown e i titoli nella forma grezza e crittografata per ogni messaggio (crittografati utilizzando la chiave di conversazione).
-
Accettare il limite secondo cui il server conosce chi ha parlato con chi e quando (stiamo proteggendo solo il “cosa”). Accettare anche che la ricerca non funzionerà per questo contenuto.
Esperienza utente proposta
Jane accede alla sua pagina utente e clicca sul pulsante “attiva messaggistica crittografata”. Una volta cliccato, le verrà chiesto di inserire un segreto; l’interfaccia spiegherà chiaramente che, se dimentica questo segreto, non avrà MAI più accesso ai suoi messaggi crittografati.
Una volta attivata la messaggistica crittografata, apparirà un nuovo [ ] nell’interfaccia di creazione del messaggio con il testo [ ] crittografa messaggio. Questo sarà cliccabile solo se tutti i destinatari hanno l’opzione “attiva messaggistica crittografata” abilitata. Se alcuni non hanno chiavi pubbliche, al tentativo di cliccare apparirà il messaggio: “Spiacente, ma alcuni partecipanti non hanno la messaggistica crittografata abilitata”.
Jane decide di voler parlare in privato con Pete; lo aggiunge all’elenco dei partecipanti, clicca su crittografa messaggio e invia un messaggio a Pete.
Pete riceve una notifica che indica che Jane gli ha inviato un messaggio crittografato. Non c’è un titolo, solo l’informazione che esiste un messaggio crittografato e i link al messaggio (sia nelle notifiche via email che in quelle web).
Se Pete è sul dispositivo originale su cui ha abilitato la messaggistica crittografata, la sua passphrase segreta è già stata inserita e le credenziali sono già salvate in IndexedDB. Se Pete è su un nuovo dispositivo, gli verrà chiesto di inserire la sua passphrase segreta per attivare la messaggistica crittografata.
L’interfaccia mostrerà chiaramente un overlay o un hint visivo per indicare che il messaggio è crittografato.
Una volta avviata la comunicazione tra Jane e Pete, uno dei due può invitare nuove persone al messaggio, purché abbiano chiavi pubbliche.
Pete o Jane possono modificare la passphrase segreta quando vogliono; in tal caso, la chiave privata verrà ricrittografata con la nuova passphrase e inviata al server. (Per la V1 non sarà consentito modificare la chiave privata vera e propria, ma solo la passphrase).
Dettagli tecnici
In nessun momento verranno inviate al server conversazioni private non crittografate o credenziali private. L’unica fiducia riposta nel server sarà che nessuno abbia manipolato il payload JavaScript inviato al client.
Le coppie di chiavi pubbliche e private verranno generate al 100% lato client; successivamente, la chiave privata verrà crittografata utilizzando la crittografia simmetrica AES prima di essere consegnata al server per la conservazione. La passphrase verrà allungata utilizzando un sale generato casualmente e memorizzato sul server. L’allungamento della chiave avverrà lato client utilizzando PBKDF2 (disponibile nell’API Web Crypto). La coppia di chiavi privata/pubblica verrà memorizzata lato client in IndexedDB utilizzando un oggetto CryptoKey non esportabile. I dati di CryptoKey esportabili verranno rimossi dalla memoria il prima possibile.
La chiave privata crittografata e la chiave pubblica verranno memorizzate in campi personalizzati dell’utente. Solo current_user potrà leggere/scrivere la chiave privata crittografata; tutti gli utenti loggati potranno leggere le chiavi pubbliche di tutti gli utenti.
Le chiavi di conversazione verranno generate lato client all’avvio della conversazione o durante un invito e crittografate utilizzando tutte le chiavi pubbliche coinvolte nella conversazione. Questi dati verranno memorizzati in una tabella dedicata (user_id, topic_id, encrypted_conversation_key); questa riga potrà essere creata da qualsiasi utente nella conversazione, ma sarà leggibile solo da current_user == user_id.
Sarà prestata particolare cura per non esporre mai dati non crittografati al server, incluso assicurarsi che le bozze non vengano salvate in chiaro.
Per evitare una vasta categoria di errori, verranno utilizzati nuovi elementi DOM (con nuovi ID) per la modifica e l’anteprima del compositore. L’attuale .d-editor-input conterrà solo blob crittografati e l’anteprima tradizionale verrà disabilitata (ciò significa che saranno in gioco due aree di testo: una crittografata e una non crittografata). La crittografia verrà fortemente debouncata per evitare problemi di prestazioni.
Per la V1 (e per l’ambito di questo lavoro), siamo disposti a eliminare determinate funzionalità, tra cui il supporto per il caricamento di file, la visualizzazione dei link (oneboxing) per i contenuti crittografati e altri casi limite complessi.
Siamo d’accordo nel decrittare, elaborare e passare l’HTML attraverso un whitelister in tempo reale durante il rendering di questo contenuto privato.
Requisiti di documentazione
Prima dell’implementazione, verrà creata una specifica molto dettagliata, inclusi mockup web e, soprattutto, una panoramica dettagliata della sicurezza.
Requisiti di test
Questo plugin deve includere un set completo di test unitari e di integrazione sia lato client che lato server. Se accettate questo progetto, scrivete i test fin dall’inizio; non aspettate la fine del progetto per integrarli.
Preoccupazioni
Molte delle preoccupazioni sollevate in: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/ non sono più rilevanti grazie all’API Web Crypto (generazione di byte casuali veri, archiviazione delle chiavi private e così via). L’unico vettore principale che esiste è il server che invia al client JavaScript dannoso. Nel breve termine, gli utenti saranno semplicemente tenuti a fidarsi del server, come fanno con 1Password, LastPass e altre interfacce di sicurezza web. Nel lungo termine (v3/v4 - l’anno prossimo o dopo), potremmo considerare la distribuzione di un’estensione per browser che mostra un lucchetto sui siti in cui tutti gli hash di stabilità dei payload JS sono ben noti.
L’API WebCrypto è ancora relativamente giovane, ma ampiamente supportata; il plugin dovrebbe funzionare su tutti i browser da noi supportati.
Mockup semplici e approssimativi
* all’avvio di un messaggio, l’utente può scegliere di crittografare la conversazione; verrà visualizzato un avviso se uno dei partecipanti non ha chiavi pubbliche.
* gli utenti possono attivare la messaggistica crittografata cliccando quel pulsante e seguendo un’interfaccia che genera la coppia di chiavi.
Se la messaggistica crittografata è abilitata, dovrebbe semplicemente visualizzare “Hai la messaggistica crittografata abilitata”.
* Un’icona o un overlay di qualche tipo indicherà che un messaggio è crittografato.
Budget
Si tratta di un progetto molto complesso da realizzare, che richiede un’integrazione profonda e un’attenta revisione. Ci aspettiamo che sia estremamente ben testato (utilizzando sia test lato client che lato server). Il nostro budget attuale per un MVP è di 10.000 USD.


