Come crittografare i dati nel frontend / backend con una chiave che non è memorizzata da nessuna parte ed è nota solo al proprietario?

2

Ho letto un sacco di risposte e tutorial su come la crittografia lato client non è una buona idea a causa di molti motivi elencati principalmente in Crittografia Javascript considerato dannoso articolo. Alcuni fatti

  1. L'app utilizzerà HTTPS
  2. Ci sarà la convalida lato server e client
  3. Non esiste alcun collegamento tra la password dell'utente e il seguente scenario
  4. Il lato server è un servizio web RESTful (nessuna sessione di sorta)
  5. Il back-end invia JWT agli utenti
  6. Il back-end potrebbe consentire sia l'utente / password sia l'oauth (ad esempio fb, twitter, ecc.)

Che cosa voglio crittografare nel lato client?

L'utente inserirà alcune informazioni personali (ad esempio nome, indirizzo, numero di telefono) tramite un'app di frontend (ad es. Vue.js, Angular, React, ecc.)

Come immagino funzionerà?

L'utente seleziona i campi (cioè i bit e le informazioni delle informazioni personali), quindi fa clic su Cripta. L'utente fornirà una chiave di crittografia. Il frontend userà un po 'di js crypto library e cripterà le informazioni e le sostituirà in DOM e informerà l'utente sul backup della chiave di crittografia.

Come posso comunicare queste informazioni al server?

Il frontend eseguirà una richiesta HTTP PUT o POST con le informazioni personali (sia semplici / di testo o incomprensibili) sul server. Il server non si preoccupa dei dati in arrivo (ad eccezione di SQL o altre forme di iniezioni) e lo memorizza nel database immediatamente. Questa richiesta non conterrà il encryption key ma, potrebbe contenere un flag / s per specificare quali campi sono stati crittografati.

Come decifrare?

Quando l'utente richiede l'informazione, il backend restituisce qualsiasi cosa ci sia nel server così com'è. Le informazioni se crittografate verranno visualizzate come gibberish per l'utente. Usando i flag, il sistema fornirà loro l'opzione decrypt e facendo clic su questo si chiederebbe loro di inserire encryption key e la decrittografia localmente.

Scopo ultimo?

Prima di tutto, ci impegneremo a fare in modo che server e database e tutto siano a prova di proiettile ma, se per qualche motivo il server viene violato, l'hacker finirebbe con un sacco di informazioni legate a parole senza senso informazione personale.

La domanda definitiva

Leggendo attraverso internet, la crittografia in Javascript è strongmente scoraggiata quindi, le mie domande

  1. Tenendo conto dello scenario e dei requisiti di cui sopra, quali sono i rischi che impongono la suddetta implementazione?
  2. Esiste un approccio che raccomandi, in cui solo l'utente ha il controllo della chiave, non memorizzato da nessuna parte?
  3. Se dovessi crittografare queste informazioni nel back-end, come posso comunicare la encrypt key in modo sicuro con l'utente? Forse crittografare le informazioni utilizzando la chiave xyz e quindi fornire un collegamento sicuro all'utente per fare clic e visualizzare la chiave di crittografia xyz , ...?
  4. Quali altri suggerimenti ci sono per la crittografia front-end e back-end?

Vorrei dare all'utente la certezza che solo loro sanno come decrittografare la chiave. Come posso ottenerlo in un modo più efficiente? Senza dover archiviare e gestire la chiave di crittografia?

Aggiornamento 17 luglio 2018

Sulla base della risposta accettata, ho scritto un post medio su come ho implementato la soluzione qui è il link link

    
posta Raf 14.06.2018 - 23:00
fonte

1 risposta

3

Dopo la registrazione iniziale dell'utente, generare una chiave di crittografia strong utilizzando un generatore di numeri pseudocasuali crittograficamente sicuro; questa chiave servirà come chiave di crittografia dei dati (DEK) per crittografare i dati dell'utente. Ma tu non vuoi memorizzare il DEK ovunque, almeno nella sua forma in chiaro. Si desidera derivare una chiave di crittografia dalla password dell'utente, utilizzando una funzione di derivazione della chiave come PBKDF2. Utilizzare la chiave derivata dalla password dell'utente (Key Encryption Key o KEK) per crittografare il DEK. Quindi puoi tranquillamente memorizzare ciphertext di quel DEK nel database.

Ogni volta che l'utente effettua il login, non solo devi autentificarli ma anche ricavare il KEK di nuovo dalla loro password, quindi usare quella chiave derivata per decrittografare il testo cifrato del DEK. Memorizza DEK nella sessione sul server, non nel client. Ora sei in affari; è possibile utilizzare DEK per decrittografare le informazioni sul lato server per tutto il tempo in cui la sessione è attiva, ma non dopo la scadenza della sessione. Questo ha il vantaggio che l'utente non deve fissare un testo cifrato ingannevole. Puoi invece avere un elemento DOM contenitore segnaposto che dice "crittografato" o qualcosa, e forse ascoltare i clic su quell'elemento, che quindi invoca una chiamata a un endpoint API, che preleva il testo cifrato dal database, lo decrittografa sul server con il DEK che hai archiviato nella sessione, quindi lo restituisce al client come testo semplice proprio allora e là, dove puoi inserirlo nell'interfaccia utente affinché l'utente possa vederlo. Non è necessario memorizzare dati sensibili sul client, né è necessario eseguire operazioni crittografiche sul client. Questo approccio ha anche il vantaggio che il DEK può rimanere costante nel tempo. Se l'utente cambia la sua password, basta ricavare un KEK dalla nuova password e crittografare nuovamente lo stesso DEK di prima con il nuovo KEK e memorizzare il nuovo testo cifrato del DEK nel database come prima.

    
risposta data 14.06.2018 - 23:51
fonte

Leggi altre domande sui tag