Da dove dovrebbero provenire i valori di hash salt?


12

Quando si aggiungono valori salt a un valore hash per qualcosa come una password che non può essere memorizzata in testo normale, qual è il posto migliore per ottenere i valori salt? Per il contesto, supponiamo che questo sia per le password su un accesso alla pagina web.


@DevArt, ho pensato che fosse più adatto qui perché richiede una risposta molto soggettiva. Un valore salt potrebbe essere estratto da qualsiasi luogo, quindi sto chiedendo "Dove pensi sia la posizione più sicura da cui estrarre i valori salt: client o server?"
Morgan Herlocker,

Risposte:


7

Di solito ho una colonna created TIMESTAMPin una tabella utente in modo da poter vedere quando l'utente si è registrato. Non mi piace aggiungere una colonna aggiuntiva per Salt, quindi uso la colonna timestamp come salt:

SHA1(password + created)

Sto quindi assumendo che quando l'utente accede di nuovo, si tira la data in base al nome utente quando si rehash per la verifica?
Morgan Herlocker,

1
@Prof: Sì, proprio come fai se hai una colonna specifica per il sale, quindi nessuna differenza in quella prospettiva.
Jonas,

7

Importa?

Il sale ha due scopi. Rende poco pratico l'uso di grandi tabelle di password prehashed ("tabelle arcobaleno") e rende le password identiche diverse dall'elenco degli hash. Rendere diverse le password identiche aiuta a evitare un problema in cui diverse persone utilizzano una determinata password, che è presumibilmente una comune debole.

Pertanto, ogni account dovrebbe avere il suo sale unico e i sali non dovrebbero essere eccessivamente prevedibili, nel senso che non ci sarà un gruppo di sali che potrebbero verificarsi. (Se molti siti sono partiti da 1 e contati, i cattivi potrebbero costruire tabelle arcobaleno tra cui sali a basso numero, per esempio.) Non devono essere casuali in nessun senso se non generalmente imprevedibili. Non sono più segreti dell'hash stesso, quindi non hanno bisogno di essere specificamente indecifrabili.

Utilizzare qualsiasi metodo conveniente per generare un sale. Se ci sono molti potenziali valori salt (i primi sistemi Unix usavano spesso due byte, per un possibile numero di 65536) rispetto al numero di account, l'assegnazione semi-casuale non darebbe quasi mai un doppio sale.


1
In genere ho visto il secondo problema - password identiche dall'aspetto diverso - risolto concatenando il nome utente, il salt e la password e cancellando l'intera stringa. Ciò elimina la necessità di generare un sale unico per account.
Grotta di Giustino,

1
@Justin: interessante, non avevo mai visto il nome utente usato come parte dell'hash, ma è davvero un buon modo per aggiungere un po 'di entropia. Userei comunque un sale pseudo-casuale, solo perché non costa molto generarne uno.
Matthieu M.,

2
@Matthieu Con il rovescio della medaglia di doverlo archiviare da qualche parte, e se entrambi i lati di una transazione ne hanno bisogno, è necessario inviarlo anche. Con il nome utente, entrambe le parti lo sanno già.
Matthew Frederick,

2
@Justin: nel qual caso stai usando il nome utente come salt. Risponde ad entrambi gli scopi del sale: rendere impraticabili le tabelle arcobaleno e rendere le password simili diverse.
David Thornley,

@David - Vero, puoi vederlo come il nome utente che diventa parte del sale. Vorrei ancora un sale aggiuntivo in modo che l'attaccante non possa utilizzare una tabella arcobaleno per trovare le combinazioni nome utente / password. Senza un esplicito salt, stai semplicemente aumentando la dimensione della stringa di cui l'attaccante ha bisogno dalla tabella arcobaleno della lunghezza del nome utente (che probabilmente è breve e completamente minuscolo o completamente maiuscolo). Un sale costante è sufficiente per contrastare un attacco di tavolo arcobaleno a meno che il tuo sito non sia abbastanza grande da consentire a un attaccante di generare un tavolo arcobaleno specifico del sito.
Grotta di Giustino,

3

Ogni volta che si desidera memorizzare una nuova password (registrazione, reimpostazione password, aggiornamento password), una buona tecnica è:

  • generare nuovo sale
    • utilizzare un generatore di numeri pseudo-casuali sicuro crittograficamente
    • usa un sale di dimensioni decenti - un buon valore è la dimensione del blocco dell'algoritmo hash sottostante (potrebbe essere SHA-256)
  • genera un nuovo token password
    • crea una funzione hmac dall'algoritmo hash sottostante (potrebbe essere SHA-256) usando il sale come chiave hmac
    • for i in (0...65536) { password = hmac(password) }
    • il risultato delle applicazioni iterate della funzione hmac è il token password
  • memorizzare il salt e il token password
    • non memorizzare la password originale
    • facoltativamente memorizzare l'algoritmo di hash sottostante e gli allungamenti per la rilevabilità

1

Sfrutta il framework. In .NET è possibile utilizzare RNGCryptoServoiceProvider ...

        // If salt is not specified, generate it on the fly.
        if (saltBytes == null)
        {
            // Define min and max salt sizes.
            int minSaltSize = 4;
            int maxSaltSize = 8;

            // Generate a random number for the size of the salt.
            Random  random = new Random();
            int saltSize = random.Next(minSaltSize, maxSaltSize);

            // Allocate a byte array, which will hold the salt.
            saltBytes = new byte[saltSize];

            // Initialize a random number generator.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

            // Fill the salt with cryptographically strong byte values.
            rng.GetNonZeroBytes(saltBytes); 
        }

Altri framework dovrebbero avere classi simili che puoi sfruttare. Per ottenere la casualità, il software spesso impiega l'utente rispetto a Randomquanto sopra menzionato. Spostare casualmente un mouse in un'area definita per fornire sale è un'opzione utilizzata da TrueCrypt. Si riduce alle tue esigenze specifiche e al livello di sicurezza; poiché il tuo sale potrebbe semplicemente essere !@#$%.


1

Generare un lato server salt e assegnarlo a un account utente al momento della sua creazione. Meglio usare alcune API di cripto-generazione disponibili con il tuo framework ma in linea di principio qualsiasi sequenza lo farà.

Di solito le cose vengono memorizzate in questo modo:

User
-------------------
ID
Username
PasswordHashWithSalt

Esempio:

PasswordHashWithSalt =

A15CD9652D4F4A3FB61A2A422AEAFDF0DEA4E703 j5d58k4b56s8744q


Assegnalo in base a cosa però? Non deve provenire da un valore che rimarrà in posizione in modo che possa essere replicato quando l'utente accede nuovamente dopo la creazione?
Morgan Herlocker,

Con "assegnazione" intendo generare una coppia salt per nome utente / password (account) e memorizzarla nel database. Quando è necessario eseguire l'accesso, utilizzare quel sale memorizzato per controllare le cose.

1

Usa bcrypt e leggi questo articolo quanto ai normali hash non è una protezione seria in questi tempi.

Prendi in considerazione l'utilizzo del protocollo SDR zero knowledge password che ha molte librerie opensource ed è privo di brevetti.

I DSP richiedono sale e il posto migliore per ottenerlo è il cliente; il tempo in cui i loro tasti, i movimenti del mouse, cancellano le variabili di ambiente, i numeri casuali, i tempi di creazione dei file nella loro cartella temporanea, per rendere il sale alla fine in modo imprevedibile lontano dal tuo server. SDR prende il sale, un grande numero primo, la password dell'utente e genera una chiave di verifica. Non memorizzi una password che non lascia mai la loro macchina ma puoi verificare che abbiano la password che accompagna la chiave del verificatore e il salt. È immune dall'uomo nel mezzo e dagli attacchi del dizionario. Cifrare le chiavi e salt nella colonna del database solo per essere sicuri.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.