Keyed-hashing una password con un hash della password + sale come chiave, è sicuro?

2

Stavo guardando il nostro sistema di autenticazione che blocca le password in modo diverso da come mi è stato insegnato. Il sale è un array di byte costante e utilizza la password + il sale come chiave per l'algoritmo di hashing della password.

public byte[] GetHash (string password)
{
    var hmac = KeyedHashAlgorithm.Create("HMACSHA512");
    hmac.Key = HashAlgorithm.Create("SHA512").ComputeHash(this.salt + password);
    return hmac.ComputeHash(password);
}

Ho rimosso la conversione in matrici di byte, ma ho semplicemente messo,

var hash = keyedHash(hash(salt+password), password);

Questo è un modo sicuro di password di hashing? Mi è stato sempre detto che il sale dovrebbe essere generato ogni volta che una password viene hash e memorizzata insieme alla password.

    
posta user38044 28.01.2014 - 03:14
fonte

2 risposte

3

Questo metodo di hashing è una costruzione fatta a mano, che, come quasi tutte le costruzioni fatte a mano, è debole.

In questo caso, commette i due peccati cardinali dell'hash della password:

  • La funzione di hashing consente attacchi paralleli.
  • La funzione di hashing è troppo veloce.

Qui, se due utenti hanno la stessa password, terminano con lo stesso hash. Ciò significa che se l'hacker ha un migliaio di hash di password con cui lavorare (ad es. Ha scaricato la corrispondente tabella di database attraverso un'iniezione SQL), può hash una password potenziale e cercare il valore hash nella tabella: l'attaccante attacca 1000 password contemporaneamente, per circa lo stesso costo di attacco. Questo è molto brutto. I sali sono pensati per evitarlo, ma funziona solo se ogni sale è usato per la password hash one , non per tutte le password hash su un dato server.

Per quanto riguarda la velocità: un PC di base passerà attraverso diversi milioni di istanze SHA-512 al secondo. Non molte password scelte dall'utente resistono a lungo quando l'aggressore può provare milioni al secondo ...

Il suggerimento di @jj28 è in qualche modo migliore, ma non così ottimale come si potrebbe desiderare. L'utilizzo di un hash del nome utente concatenato con un valore globale del server (ma distinto da server a server) garantisce una sorta di univocità mondiale; tuttavia, se un utente cambia la sua password, allora userà lo stesso "salt" (poiché si trova sullo stesso server, e l'utente non ha cambiato nome, solo password). L'attaccante che potrebbe ottenere gli hash della vecchia e della nuova password sarà comunque in grado di attaccare entrambi in parallelo. Questo è migliore del metodo precedente, ma non è ancora perfetto.

Inoltre, il problema di velocità rimane ed è abbastanza serio da giustificare un anatema su questa proposta.

Leggi questa risposta per sapere come deve essere la password hash, e quali concetti teorici sono al lavoro qui. La risposta breve è: usa bcrypt .

    
risposta data 28.01.2014 - 15:11
fonte
1

Considero il sale costante per tutti gli utenti? Anche se è meglio di niente sale, rende ancora più semplice un attacco di forza bruta: possono forzare brutalmente tutti gli account utente in una sola volta. Rivela anche quando due utenti hanno la stessa password.

Tuttavia, considera questa variazione minore:

hash = keyedHash(hash(system_salt+username), password);

Questo è fondamentalmente ok. Normalmente non lo consiglierei - è più prudente usare i sali casuali per utente - ma ti guadagna le proprietà richieste di un sale.

    
risposta data 28.01.2014 - 11:24
fonte

Leggi altre domande sui tag