Il sale deve essere unico o non prevedibile?

11

Ho sempre pensato che i sali siano semplicemente usati per prevenire l'uso di tavoli arcobaleno. Altri hanno suggerito che dovrebbero essere unici su base account. Attualmente sto usando un file di configurazione da usare come sale. In passato ho fatto md5 (salt + password) ma ora uso .NET PBKDF2 tramite (pass, salt_from_config) .

Ho sbagliato o no? I sali dovrebbero essere unici o semplicemente non prevedibili, quindi nessuno può generare un tavolo arcobaleno prima del tempo?

    
posta curiousguy 21.07.2012 - 04:27
fonte

3 risposte

12

Ho pubblicato una risposta che spiega ciò su un'altra domanda , che dovrebbe dare un buon background a tutti i principali problemi di sicurezza relativi all'archiviazione delle password.

Per rispondere alla tua domanda più direttamente: a salt:

  • deve essere unico.
  • dovrebbe essere imprevedibile.
  • dovrebbe essere sconosciuto ai potenziali aggressori.

Il problema con schemi come H(pass + username) è che l'attaccante conosce il sale. Così, mentre la sua capacità di decifrare ogni password nel database con una singola tabella arcobaleno è andata, lui può creare una tabella arcobaleno per gli account utente chiave. Ciò gli consente di calcolare in anticipo la tabella arcobaleno per un account utente privilegiato (ad es. Admin), quindi utilizzarla immediatamente una volta che ha violato il database.

Questo è un problema, perché non ti dà il tempo di reagire alla violazione. Alcuni secondi dopo essere stato avvisato dell'attacco, l'utente malintenzionato ha effettuato l'accesso al proprio account amministratore. Se l'utente malintenzionato è costretto a rompere la password dopo la violazione, ti dà il tempo di bloccare gli account con privilegi e modificare le password.

Puoi anche esaminare uno schema sale + pepe, in cui il pepe è un secondo sale memorizzato all'esterno del database, ad es. nel codice. Questo aiuta a prevenire il modello di attacco di SQL injection, in cui il malintenzionato ha accesso al database.

La best practice è qualcosa come questa (sentiti libero di omettere il pepe):

hash = KDF(pass + pepper, salt, workFactor)

Dove:

  • KDF è una funzione di derivazione chiave strong e lenta, come bcrypt di PBKDF2.
  • pass è una password complessa (applica le norme sulle password!)
  • pepper è un valore costante casuale lungo memorizzato nel tuo codice.
  • salt è un valore univoco casuale lungo memorizzato con la password nel database.
  • workFactor è appropriato per i tuoi requisiti hardware e di sicurezza.
risposta data 21.07.2012 - 10:08
fonte
8

I sali dovrebbero essere unici per ogni password.

Se stai usando lo stesso sale per ogni password, un utente malintenzionato potrebbe semplicemente generare una tabella arcobaleno usando quel particolare salt e crackare la maggior parte delle password nel tuo database.

Per quanto riguarda i commenti sull'accelerazione di PBKDF2 e GPU, vorrei indicarti questo link proprio qui a Security.SE, dove Thomas Pornin ha dato una risposta eccellente.

    
risposta data 21.07.2012 - 04:43
fonte
1

I requisiti esatti per un sale dipendono dall'algoritmo di hashing della password, ma per i soliti metodi (bcrypt, PBKDF2 ...) il requisito solo è che il sale sia univoco . O almeno così unico come è pratico; la collisione dispari non è un grosso problema se non accade spesso e non può essere forzato dall'esterno.

L'unicità è mondiale; non è sufficiente che i sali siano unici in un dato server. Due server distinti, che utilizzano lo stesso algoritmo di hashing, dovrebbero avere anche sali distinti.

Un modo relativamente comune ed economico per ottenere l'unicità in tutto il mondo è quello di generare sali da un PRNG crittograficamente strong, con una lunghezza sufficiente (sono sufficienti 16 byte casuali). Questo è ciò che fa bcrypt . Se il PRNG è di parte, allora hai bisogno di un sale un po 'più lungo per raggiungere l'unicità. Se il PRNG è debole a causa di un seme troppo piccolo o di uno stato interno, allora l'unicità non sarà ottenuta in modo soddisfacente in questo modo. Il nome utente è non buono, per due motivi:

  • Lo stesso nome utente può verificarsi in diversi server (ad esempio, ogni server potrebbe avere un account "Amministratore", con quel nome esatto);
  • L'utente non cambia il suo nome quando cambia la sua password, portando al riutilizzo di sale.

Sali non sono la stessa cosa di chiavi (che sono segreti e devono rimanere confidenziali) o vettori di inizializzazione (IV sono "punti di partenza" per alcuni algoritmi e possono avere requisiti aggiuntivi come uniformità e imprevedibilità nel caso della crittografia CBC). Normalmente non vi è alcun problema nel dare via i valori del sale; in ogni caso, chiunque ricalcoli il valore hash della password deve conoscere il sale. Pertanto, la pubblicazione di sali è intrinseca con la crittografia basata su password dei file (il sale viene quindi codificato nell'intestazione del file). È inoltre necessariamente pubblicato nei protocolli di autenticazione in cui avviene l'hashing sul client (cosa abbastanza rara nei contesti Web, perché Javascript è troppo lento). Non ha senso pubblicare i sali senza necessità, ma mantenerli segreti non migliora realmente la sicurezza.

In questa risposta , viene evocato uno scenario marginale: un l'attaccante apprende il sale in anticipo, prepara una grande tabella precomputed, quindi esegue l'attacco effettivo che rivela l'hash della password. Ciò non rende più facile per l'utente malintenzionato la violazione della password; di fatto, questo aumenta il suo sforzo (deve produrre una tabella completa invece di fermarsi quando viene trovata la password, quindi è un doppio costo in media; se la tabella è della persuasione arcobaleno, entra un fattore 1,7 aggiuntivo per la generazione di tabelle; ci sono costi di archiviazione). Ciò che cambia è la dinamica : questo riduce il tempo tra l'irruzione (il valore hash viene rubato) e il recupero della password. Questo è un caso limite, quindi non preoccuparti. Se si utilizza l'hashing della password per la memorizzazione in un protocollo di autenticazione, dove si verifica l'hashing sul lato server, è sufficiente memorizzare il sale con il valore hash e i sali saranno confidenziali come i valori hash stessi, e ciò è positivo. In altri casi (ad es. Crittografia dei file basata su password), i sali saranno più "pubblici", ma non è fondamentale in alcun modo, quindi non aggiungere l'aggiunta di complessità per mantenere i sali segreti (complessità extra è cattiva e molto peggio dei sali pubblici)

    
risposta data 29.10.2012 - 15:59
fonte

Leggi altre domande sui tag