Javascript - Crittografia lato client / archiviazione chiavi

5

Mi rendo conto che questo è spesso descritto come una cattiva idea. Quindi, prima di tutto, spiegherò la motivazione: sentiti libero di criticare questo.

Creazione di un prodotto per un'industria che tende ad essere eccessivamente preoccupata per la sicurezza. Il prodotto deve memorizzare e restituire i file dell'utente, ma non è necessario che siano leggibili dal lato server.

Ritengo che la crittografia del lato client ridurrebbe la fiducia richiesta dai clienti. I loro dati riservati sarebbero toccati solo da JavaScript che potevano ispezionare e monitorare. Significa anche che qualsiasi problema di sicurezza sul lato server che consentirebbe l'accesso ai dati archiviati non comporta la disponibilità di documenti client (a eccezione se possono modificare JS servito).

La mia soluzione ideale sarebbe -

- Key generated and injected to all clients users by clients IT team.
- JavaScript uses key to encrypt documents client side. These are then sent to the server and stored.
- On retrieval documents are decrypted again client side.

Sembra che ci siano diverse librerie per supportare la crittografia lato client. Ma attualmente non vedo alcun modo per memorizzare in modo persistente una chiave per l'utente. Idealmente, questo sarebbe in modo simile all'aggiunta di certificati al negozio di browser, vale a dire che possono essere iniettati una sola volta.

Qualcuno ha qualche suggerimento?

    
posta Hector 13.09.2017 - 17:55
fonte

3 risposte

2

(Per essere chiari: questo protegge solo gli utenti in situazioni in cui l'autore dell'attacco riceve solo un accesso di sola lettura e protegge gli utenti che non hanno utilizzato il sito da quando un utente malintenzionato ha sostituito il javascript con una versione malevola. sei malizioso fin dall'inizio, a meno che l'utente non verifichi accuratamente / registri tutto il javascript che il tuo sito li consegna.Se quest'ultima parte è importante per te, potrebbe esserci un modo per utilizzare ServiceWorkers per avvisare gli utenti ogni volta che una nuova versione del javascript del tuo sito è eseguito, ecc, ma questo è per un'altra domanda.)

È possibile memorizzare le chiavi di crittografia localmente nel client con localStorage o IndexedDB. Le chiavi di crittografia potrebbero essere stringhe utilizzate dal tuo client javascript.

Sui browser di supporto, per una maggiore sicurezza è possibile utilizzare invece l'API Web Crypto (+ IndexedDB). Con l'API Web Crypto, puoi generare chiavi in javascript e usarle per la crittografia / decrittografia, ma il codice javascript non può accedere al materiale della chiave non importa quale. Ciò significa che anche se un utente malintenzionato accede al tuo server un giorno e sostituisce il javascript con una versione malevola, non può sostituirlo con una versione che perde le chiavi degli utenti. (Tuttavia, potrebbero sostituirlo con una versione che consente ai client di scaricare i loro file, decrittografarli e caricarli di nuovo sul server in background la prossima volta che visitano il sito. Ciò richiederebbe tempo e potrebbe essere evidente agli utenti e / o te, quindi potrebbe darti il tempo necessario per correggere il problema prima che tutti i dati dell'utente siano trapelati.)

    
risposta data 14.09.2017 - 00:36
fonte
0

Se controlli il codice sorgente lato server:

Il mio suggerimento è di archiviare almeno 4 chiavi sul backend che si ruotano e il lato server di crittografia simmetrica utente che esegue il lato tutto il server di crittografia e decrittografia.

Ho avuto un caso di utilizzo simile in cui il mio flusso di lavoro era (con la crittografia di Fernet):

  • L'utente carica i dati e viene crittografato con 1 delle 10 chiavi (ruotate) quindi memorizzato nel database

  • Sulla query dopo ho ottenuto se dal DB quindi decrittografarlo e inviarlo al frontend

I vantaggi:

  • Più sicuro quindi gestisci qualsiasi tasto sul frontend

  • Se il database viene sfruttato tramite SQL injection, non è un testo semplice

Svantaggi:

  • Servono più risorse sul lato server in quanto rallenta il processo

  • Le chiavi sono ancora lato server di testo normale, quindi se la macchina host è stata compromessa, non c'è aiuto da parte sua, ma è ancora attaccante come 1 passo in più per accedere ai dati.

Se non controlli il codice lato server:

Il meglio che puoi fare è memorizzare la chiave simmetrica nel database e sulla registrazione dell'utente generarne una per ciascuno. Dopo l'accesso, salvalo nel cookie come sessione per quell'utente

I vantaggi:

  • Facile da implementare

  • Ogni utente ha la propria chiave simmetrica se un account utente viene compromesso, gli altri utenti non possono essere decodificati

Svantaggi:

  • I cookie possono essere rubati quindi non è necessario avere un'intestazione iframe

  • Se non utilizzati attacchi HTTPS e HSTS mitm puoi facilmente ottenere i dati

Ma non prendere il mio suggerimento come Santo Graal aspettare e ricercare più fonti allora è su di te decidere. ;)

    
risposta data 13.09.2017 - 19:52
fonte
0

I feel that by encrypting client side would reduce the trust required from clients. Their confidential data would only be touched by JavaScript which they could inspect and monitor.

Questo non è proprio vero. Nessuna persona normale può effettivamente ispezionare e monitorare javascript dal browser scaricato da un sito, e se mi fido del server / amministratore del server / degli sviluppatori di software server abbastanza da credere che non mi mandano javascript con una backdoor, potrei anche fidati di loro per memorizzare i miei file.

Sono d'accordo sul fatto che si tratta di un ulteriore livello di sicurezza, ma è talmente semplice da togliere che sembra quasi inutile implementarlo. Protegge da alcuni scenari di minacce - ad esempio, probabilmente protegge i backup oi vecchi dischi rigidi che non vengono cancellati dai dati del cliente - ma in realtà non riduce la fiducia che i client devono inserire nel fornitore di servizi di molto. / p>

But Currently I see no way to persistently store a key for the user.

Se non vuoi salvarlo nella memoria del browser lato client, potresti

a) Chiedere all'utente di fornire al client javascript una passphrase, crittografare simmetricamente la chiave con la passphrase e un potente cifrario simmetrico e inviare la chiave al server per essere memorizzata lì

b) Visualizza la chiave come codice QR e fai scattare una foto con il suo cellulare. Quando è necessario il tasto indietro, l'utente può copiare e incollare la stringa di chiavi che il codice QR risolve per tornare nell'app javascript lato client. È molto complicato, però.

    
risposta data 14.09.2017 - 00:16
fonte

Leggi altre domande sui tag