Crittografia lato client dei dati utente con password utente

2

Ho ristretto lo schema per consentire alla mia applicazione di crittografare il lato client dei dati utente e trasmettere tali dati al server, senza che il nostro server sia in grado di decodificare i dati.

Voglio assicurarmi che non ci siano evidenti difetti in questo schema.

Metodo

Nota: ogni passaggio seguente avviene sul lato client.

Precursore:

  1. Dopo l'accesso / registrazione, genera la chiave globale gk = SHA256(user_password) e salva gk in un cookie localStorage. (La ragione di ciò è di non memorizzare chiaramente la password dell'utente.)

Crittografia:

  1. Per ogni file, genera una chiave casuale fk .
  2. Cifra file con fk .
  3. Encrypt fk con gk per ottenere fk .
  4. Trasmetti il file crittografato e fk ' al server per l'archiviazione.

decrittografia:

  1. Ricevi file crittografato e fk ' dal server.
  2. Decifra fk ' usando gk per ottenere fk .
  3. Decifra il file usando fk .

Quando l'utente cambia password:

  1. Per ogni file, decrittografare fk ' usando corrente gk per ottenere fk .
  2. Genera nuovo gk utilizzando la nuova password.
  3. Encrypt fk con nuovo gk per ottenere fk .
  4. Trasmetti il nuovo file fk ' al server per l'archiviazione.

Quando l'utente dimentica la password:

  1. sfortuna. (A meno che?)

Quali difetti esistono in questa procedura?

Aggiorna

Un difetto è che se l'utente autentica il login con una password, tecnicamente, posso facilmente calcolare e memorizzare gk sul server, compromettendo così la promessa della crittografia lato client.

Una soluzione a questo:

  1. Genera pw = SHA256(SHA256(user_password)) e invialo al server come password dell'utente. Il server riceve quindi questa password e la crittografa nuovamente prima di memorizzarla.

Quindi, per quanto riguarda il server, sta solo ricevendo una password regolare. In questo modo, gk non può essere calcolato lato server.

I difetti?

    
posta Snowman 16.11.2016 - 20:54
fonte

2 risposte

5

Il più grande difetto in questo schema è che dipende dal codice javascript che verrà trasmesso al client dal (a) server.

Quindi, che cosa è mantenere il server (o un uomo nel mezzo) per inviare il javascript modificato del client che elude tutte le misure di sicurezza? In che modo il cliente o l'utente lo sapranno mai? Tutto il codice che scrivi per controllare le impronte digitali, i checksum, le firme digitali ecc. Può essere anche eluso.

Un altro problema correlato è un altro codice javascript dannoso in esecuzione nel browser che non può essere isolato in modo affidabile dal codice javascript relativo alla sicurezza.

Questo è impossibile da risolvere. In-Browser Javascript al momento non è una piattaforma sicura e tutta la crittografia client-side del browser soffre di questa lacuna di sicurezza che non può essere chiusa.

Riepilogo della discussione nei commenti relativi alla domanda aggiornata

Il calcolo di pw = sha256 (sha256 (user_password)) mi sembra una cattiva idea per diversi motivi.

  1. Il primo è stato già menzionato da AgentMe: non utilizzare l'hash semplice funzioni come sha-qualunque per le password hash. Queste funzioni di hash sono state progettate per essere implementate in modo efficiente nell'hardware e sono molto, molto troppo veloce; alle password hash, vuoi le funzioni hash lente. Vedi AgentMe risposta.
  2. Con questo schema, pw può essere calcolato se conosci gk (che è semplicemente sha256 (user_password)). Quindi, quando qualcuno ruba la tua cartella locale, gli dai accesso sia alla chiave di crittografia master sia al token di autenticazione / autorizzazione che deve scaricare i file crittografati. Sarebbe meglio mantenere i due segreti indipendenti l'uno dall'altro, quindi se uno viene compromesso da una terza parte, non è sufficiente calcolare l'altro e rompere la riservatezza dei dati crittografati.
  3. Infine, non stai salendo la tua user_password con questo schema. Ciò significa che password identiche su tutta la base utente produrranno valori hash identici (e ci sono già grandi tabelle arcobaleno per sha-hashes non salati là fuori contenenti le poche milioni di password più comuni).

Suggerisci un'alternativa, ad es. gk = sha256 (user_password) e pw = sha128 (user_password). Mentre questo risolve il punto 2, non affronta 1 e 3. Inoltre, non lo consiglierei perché potrei immaginare che ciò fornisca inutilmente informazioni aggiuntive a un utente malintenzionato (la stessa password è stata sostituita con due valori hash diversi), anche se io non so come sfruttarlo

Ho suggerito di usare gk = hmac (user_password, n) e pw = hmac (user_password, m), dove m e n sono noti, ma diversi per ogni utente. Il modo in cui arrivi a me n è irrilevante, a patto che siano casuali e sufficientemente grandi per renderli unici nella tua base di utenti con un'alta probabilità. È possibile crearli sul client e inviarli per la memorizzazione sul server, indicizzati dal nome utente in modo che possano essere recuperati su altri client. Oppure puoi fare in modo che il server li generi quando l'utente crea per la prima volta un account. I valori non devono essere tenuti al sicuro; sono inutili senza user_password. Un miglioramento nel miglioramento sarebbe l'utilizzo di gk = hmac (bcrypt (user_password), n) e pw = hmac (bcrypt (user_password), m) per rendere più difficili gli attacchi brute force.

Ora, non sono convinto che questo suggerimento sia una buona idea, dal momento che hmac è progettato per l'autenticazione dei messaggi, non per la creazione di token di autenticazione o chiavi di crittografia, quindi prendo questo suggerimento con un pizzico di sale. Ma sembra che risolva tutti e tre i punti che ho sollevato, quindi sembra una soluzione migliore rispetto al concatenare la stessa funzione di hash o usare due diverse funzioni di hash sulla password.

    
risposta data 16.11.2016 - 22:46
fonte
1
  1. gk deve essere memorizzato in localStorage / IndexedDB e non un cookie, perché i cookie vengono inviati al server!
  2. Dovresti utilizzare un algoritmo di derivazione password / hashing della chiave più potente di SHA256 che è più resistente alla forza bruta.
  3. In che modo l'utente si autentica sul server? Probabilmente non vuoi lasciare solo una richiesta utente o aggiornare i file fk' crittografati per qualsiasi altro utente. Ti consigliamo di autenticare gli utenti in un modo che non sia l'invio della loro password in chiaro. Potresti averli inviare il valore gk passato una seconda volta alla funzione di derivazione della chiave.
  4. Vedi link . Tu (o qualcuno che ti ha costretto o qualcuno che ti ha violato) può ottenere i dati dell'utente modificando il javascript che il server invia in modo che invii i valori di gk degli utenti al server o li rilasci in altro modo. Questo potrebbe essere mitigato con un buon uso dei lavoratori del servizio che hanno codice con revisione aperta, ma non sono sicuro che qualcuno lo abbia già fatto in modo soddisfacente.
risposta data 16.11.2016 - 22:31
fonte

Leggi altre domande sui tag