dove memorizzare il sale per "crypto_pwhash" in un'applicazione web senza memoria locale

3

Sto sviluppando un'applicazione web che memorizza i dati crittografati su un server. Voglio ricavare la chiave di crittografia e la chiave di accesso da una sola password utente, quindi voglio usare libsodiums crypto_pwhash per generare una chiave abbastanza lunga da poter essere divisa in due. L'idea è che il server non possa decrittografare i dati crittografati.

Per utilizzare questa funzione è necessario un sale. Capisco che il sale non può essere segreto, ma deve essere memorizzato da qualche parte.

  • Se lo memorizzo nel server, deve essere recuperato prima dell'autenticazione (perché è necessario ricavare la chiave di accesso). Quindi questo permetterebbe di testare se esiste un nome utente senza conoscere la sua chiave di accesso. Non sono sicuro che sarebbe un rischio per la sicurezza.

  • Posso ricavare il sale in qualche altro modo? Cosa succede se ho solo cancellato il nome utente? O la password stessa? O correrei il rischio di non avere abbastanza entropia?

posta Nathan 14.07.2015 - 12:53
fonte

3 risposte

1

La proprietà richiesta di un salt deve essere univoca, perché rende impossibile utilizzare la tabella del dizionario per l'hash inverso di tutti gli utenti con la stessa tabella.

L'altra proprietà utile deve essere imprevedibile in modo che l'attaccante non possa calcolare prima la tabella del dizionario prima di eliminare il sale. (scenario in cui è utile: l'autore dell'attacco rileva un problema di sicurezza che può utilizzare per ottenere l'hash della password, genera una tabella per il nome utente che desidera accedere, quando ottiene la password può usarlo prima di poter reagire all'attacco)

salt random fornisce le due proprietà.

Usando il nome del sito + il nome utente fornisci la prima proprietà.

la password non ti dà alcuna causa quando si genera una voce nella tabella del dizionario, si conosce la password (quella che si sta tagliando).

Se lo memorizzi sul server, puoi rispondere alla richiesta con nome utente non valido di un numero casuale della stessa dimensione dell'hash casuale (questa è solo oscurità e assolutamente nessuna sicurezza)

    
risposta data 15.07.2015 - 10:18
fonte
1

Penso che il modo per risolvere questo problema sia separare, per quanto possibile, l'autenticazione e la riservatezza. Il modo ideale per farlo sarebbe avere due password, una per l'autenticazione e una completamente indipendente per la riservatezza. Il problema è che gli utenti non sono l'ideale. Probabilmente farebbero la stessa password o aggiungere una stringa molto prevedibile fino alla fine della stringa di riservatezza.

L'altra cosa da ricordare è che siccome questa è un'applicazione web, presumo che tutti i calcoli avvengano in javascript che il server invia al client. Questo rende il tuo modello di avversario interessante. Se si sta tentando di proteggere la riservatezza da un server malevolo, ma consentendo a quel server di inviare il codice (javascript) che verrà eseguito e che avrà accesso alla password, non è davvero possibile proteggersi da un server dannoso. Nulla impedisce al server di inviarti javascript che si comporta come previsto, ma invia anche la password al server.

Quindi, sei decisamente in imbarazzo e penso che senza presupposti addizionali e un modello di avversario meglio definito, non puoi proteggere la riservatezza dei dati.

    
risposta data 16.07.2015 - 14:49
fonte
0

If I store it in the server, it must be retrieved before authentication [...]

Verrebbe recuperato alla stessa ora come autenticazione, come

select salt, pw_hash from users where name = '@name'

Dovresti usare sia salt che pw_hash per convalidare la password che l'utente ha inserito. Dovresti comunque fare attenzione a divulgare informazioni sul fatto che select abbia restituito un record oppure no, ma questo non è complicato da salt.

La tua situazione è complicata perché vuoi anche ricavare una chiave di crittografia dalla password dell'utente in modo che il server non possa fare lo stesso. Parte della confusione è dovuta al fatto che l'utente ha una singola password che non può fornire al server, ma deve in qualche modo essere utilizzata per autenticare l'utente - e quindi qualsiasi cosa venga inviata al server non è propriamente una password. Ma la maggior parte delle volte che leggi i salting e gli input di hashing saranno chiamati password.

Quindi suddividiamolo in 2 passaggi. L'utente inserisce una password. Per l'autenticazione, l'utente esegue alcuni KDF senza sale e invia il risultato "C" al server. Il server cerca il sale dell'utente, esegue il hash di sale e C e lo confronta con il suo hash memorizzato. In caso di successo, il server restituisce il sale (o lo stesso o forse uno diverso) per l'utente. L'utente combina la password e il sale usando KDF2 per ottenere la sua chiave di crittografia. Se i due KDF sono diversi, o sono tweaks l'uno dell'altro, le due chiavi generate non saranno correlate.

    
risposta data 16.07.2015 - 01:17
fonte

Leggi altre domande sui tag