Usando gli ultimi caratteri di hash come sale [duplicato]

3

In una recente discussione qualcuno ha menzionato il seguente schema di hashing:

passHash = sha256(password)
saltedHash = sha256(passHash+passHash.substr(-10)
finalHash = sha256(secret+saltedHash)

La password è stata sottoposta a hash, quindi è stata nuovamente cancellata con gli ultimi 10 caratteri dell'hash precedente come "salt". Alla fine viene aggiunto un segreto e tutto viene nuovamente sottoposto a hash prima che venga salvato nel database.

Quanto è sicuro questo? So che le password uguali avranno lo stesso finalHash. Ma a parte questo, quanto è male usare una parte della password con hash come sale? Avere un sale segreto in seguito aiuta? Quanto è male avere solo 3 iterazioni di sha256 invece di poche migliaia? C'è un attacco facile che dimostra che questo schema di hashing è una cazzata?

    
posta Lincoln 18.08.2014 - 20:13
fonte

4 risposte

17

Non farlo. I sali devono essere unici, questo è il loro unico requisito. Ma il tuo approccio non genera sali unici, ma quelli dipendenti dalla password.

Un sale per-db-unique aiuta quando è lungo abbastanza (256 bit), e hai anche hash nel nome utente, ma questo lascia comunque dei problemi.

Avere solo 3 iterazioni di SHA256 non è il modo in cui dovrebbero essere gli hash delle password, anche se non è solo un 'superiore è meglio'. Se un attaccante è impegnato a fare molte iterazioni di sha, non possono provare nuove password. Assicurati di utilizzare PBKDF2 o simili per prevenire ulteriori attacchi. Puoi prendere il logaritmo per 2 dal conteggio delle iterazioni, e poi ottieni i "bit di sicurezza" aggiunti per infrangere una password. Le iterazioni ti offrono un compromesso tra potenza di calcolo e sicurezza, ma a un tasso di conversione non efficiente (1: 1 invece di 1: exp con password).

Quello che stai facendo non è la salatura, ma cuoce una nuova funzione di hashing da un altro. Per ogni utente, crea una stringa casuale con 256 bit di entropia da un PRNG e usala come sale .

    
risposta data 18.08.2014 - 20:55
fonte
4

Risposta breve: non farlo.

Salt dovrebbe essere usato per fornire un po 'di sicurezza contro le password hash trapelate, poiché la stessa password avrà lo stesso hash, quando non è salata.

Se il sale è prevedibile, non c'è guadagno.

Dato che non stai aggiungendo alcuna entropia facendo ciò, non c'è alcun guadagno facendo quel tipo di cose.

E dal momento che stai usando un numero molto piccolo di iterazioni, lascia solo la SHA-256 troppo veloce da usare, soggetta a tutte quelle debolezze che hai detto nella tua domanda.

    
risposta data 18.08.2014 - 20:57
fonte
1

Il tuo "sale" non sembra fornire nessuno dei benefici che sono il punto di usare un sale. Usando il tuo schema, ogni password produce solo un singolo output, quindi un utente malintenzionato che conosce il tuo schema (che tu devi assumere) può facilmente produrre una tabella arcobaleno di possibili hash da abbinare a quelli del tuo database.

Si suppone che un salt prevenga questo, perché un diverso salt per ogni password significa che anche se sono la stessa password l'hash risultante sarà diverso, quindi generare una tabella arcobaleno non è fattibile, perché avrebbe bisogno di contenere non solo un hash per ogni possibile password, ma un hash per ogni possibile combinazione di password e salt.

Come altri hanno già detto, 3 l'iterazione di SHA256 sta per essere eseguita troppo velocemente. Dovresti utilizzare un meccanismo che è stato specificamente progettato per le password di hashing come BCrypt. Anche quando stai usando un meccanismo che è adeguatamente lento, non dovresti legarti permanentemente a una singola velocità o numero di iterazioni; le velocità del computer aumentano sempre e vorrai aumentare il numero di iterazioni per mantenerle in vantaggio. BCrypt ti consente di farlo senza rompere gli hash esistenti poiché codifica la forza da memorizzare insieme alla password con hash.

    
risposta data 18.08.2014 - 23:43
fonte
1

In parole povere, lo scopo di Salt è rendere l'hash diverso per la stessa password.

hash('password') == hash('password') // same password, same hash
hash('password'+salt#1) != hash('password'+salt#2) // avoid hash collision with salt

Ora prendiamo il tuo approccio ed espanderlo. È equivalente a:

finalHash = sha256(secret+sha256(sha256(password)+sha256(password).substr(-10)))

Per una determinata password, questo restituirà lo stesso valore ogni volta. Si tratta essenzialmente di una nuova funzione di hash basata su sha256 . Ciò significa che la tabella delle credenziali ha collisioni hash. Ma tu già conosci . Ma sai questo:

Ciò significa che l'autore dell'attacco potrebbe essere in grado di trovare anche secret per forza bruta (se il segreto è considerevolmente più piccolo di lunghezza, o la funzione hash ha collisioni), perché c'è sempre quel gruppo di utenti che usano 'password' , '123456' , ecc. per la loro password. L'attaccante deve semplicemente attaccare contro gli hash più comuni nel tuo database delle credenziali.

Da questo momento in avanti, il concatenamento delle funzioni di hash non ti darà molta sicurezza aggiuntiva, perché quattro chiamate a sha256 non contengono un sovraccarico pratico per un utente malintenzionato rispetto a una singola chiamata.

TL; DR: Non farlo.

    
risposta data 19.08.2014 - 06:59
fonte

Leggi altre domande sui tag