it-swarm.dev

Con PBKDF2, qual è una dimensione hash ottimale in byte? E le dimensioni del sale?

Quando si crea un hash con PBKDF2, consente allo sviluppatore di scegliere la dimensione dell'hash. È sempre meglio? Inoltre, che dire delle dimensioni del sale casuale? Dovrebbe avere le stesse dimensioni dell'hash?

EDIT: in particolare nelle password di hashing.

27
blesh

Per la funzione hash, si desidera utilizzare una funzione per la quale il tipo di piattaforma più efficiente (quello che produrrà più calcoli hash al secondo e per dollaro) è la macchina che si intende utilizzare (ad esempio un PC). Questo perché sei in una corsa alle armi con l'attaccante e l'attaccante può acquistare altri tipi di hardware per ottenere un vantaggio su di te (come una GPU). Le GPU sono molto buone con l'aritmetica a 32 bit, ma non con l'aritmetica a 64 bit, mentre un PC (in modalità 64 bit) sarà piuttosto veloce in quest'ultima.

Pertanto, utilizzare una funzione hash che viene eseguita su operazioni aritmetiche a 64 bit. Questo indica SHA-512 .

PBKDF2 è un funzione di derivazione chiave : produce un output di dimensioni configurabili. Per l'hash della password, si desidera che le dimensioni siano sufficientemente grandi da scoraggiare gli attacchi di preimage generici (ovvero tentare password casuali fino a quando non viene trovata una corrispondenza), quindi ciò dovrebbe richiedere, ad esempio, almeno 80 bit di output. Se non altro per rendere la sicurezza più convincente per gli incauti, e anche per l'estetica, scegli la potenza successiva di 2: a output a 128 bit . Non è utile andare oltre.

Il sale deve essere unico - il più unico possibile. Un modo semplice per ottenere valori di sale unici è generare sali con PRNG crittograficamente forte : la probabilità di riutilizzare un valore di sale sarà sufficientemente bassa per essere trascurata se questi sali casuali sono abbastanza grandi e "abbastanza grandi "significa" 128 bit ". Quindi usa sali casuali a 128 bit .

Personalmente, I preferisco bcrypt su PBKDF2 per l'hash della password.

24
Thomas Pornin

Secondo lo standard PBKDF2, la dimensione minima consigliata per il sale è di 64 bit, sebbene io personalmente consiglierei 128 bit o più per un margine di sicurezza decente. La dimensione del sale è indipendente dalla tua scelta di hash.

Per quanto riguarda la sicurezza, raccomando di scegliere una lunghezza della chiave derivata di almeno la stessa dimensione dell'output di Salt, con un minimo di 256 bit. Qualsiasi dimensione di hash inferiore a 256 bit è comunque al di sotto del limite di sicurezza della maggior parte delle moderne funzioni di hash.

Scegliere una lunghezza della chiave derivata inferiore alla lunghezza di output della funzione hash ha poco senso, a meno che non si usi la chiave per un codice a blocchi che non può gestire una chiave di quella dimensione.

In termini di sicurezza ottimale, suggerirei SHA-512 come PRF, con una chiave derivata a 512 bit, un salt a 128 bit e tutte le iterazioni che la tua situazione può giustificare.

11
Polynomial

Nel caso in cui la tua piattaforma preferita sia .NET, esiste un articolo OWASP dedicato in modo specifico alla sua classe Rfc2898DeriveBytes . In particolare nota (sottolineatura mia):

L'implementazione .NET integrata di Rfc2898DeriveBytes limita l'utente a una funzione psudorandom - HMAC con SHA-1 . Ciò è accettabile nella maggior parte degli scenari oggi, ma in futuro potrebbe essere necessaria una funzione di hashing più complessa.

Utilizzando PBKDF2 per l'archiviazione della password, non si dovrebbero mai generare più bit della dimensione della funzione hash di base. Con PBKDF2-SHA1 questo è 160 bit o 20 byte . L'output di più bit non rende l'hash più sicuro, ma costa molto più tempo al difensore senza costare all'attaccante. Un utente malintenzionato confronta semplicemente il primo output dimensionato della funzione hash, risparmiando loro il tempo necessario per generare il reset dell'output PBKDF2.

Hanno anche un esempio di codice, che ho modificato secondo le indicazioni delle altre risposte:

public static string Hash(string str)
{
    // Generate the hash, with an automatic 16 byte salt
    using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(str, 16))
    {
        rfc2898DeriveBytes .IterationCount = 10000 // or whatever you can afford
        byte[] hash = rfc2898DeriveBytes.GetBytes(20);
        byte[] salt = rfc2898DeriveBytes.Salt;
        return Convert.ToBase64String(salt) + "|" + Convert.ToBase64String(hash);
    }
}
4
Ohad Schneider