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.
- 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.
- 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.
- 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.