Come implementare le iterazioni quando le password di hashing?

1

Per password di hash sicure, algoritmi come PBKDF2 eseguono molte iterazioni di un hash comune come SHA1. Ci sono alcuni modi in cui queste iterazioni devono essere fatte per essere al sicuro?

In particolare, da password-hash.js :

function generateHash(algorithm, salt, password, iterations) {
  iterations = iterations || 1;
  try {
    var hash = password;
    for(var i=0; i<iterations; ++i) {
      hash = crypto.createHmac(algorithm, salt).update(hash).digest('hex');
    }

    return algorithm + '$' + salt + '$' + iterations + '$' + hash;
  } catch (e) {
    throw new Error('Invalid message digest algorithm');
  }
}

È un modo sicuro per cancellare la password? Posso immaginare che se hai un algoritmo come questo che fa:

HMAC(HMAC(HMAC(password)))

quindi esiste una funzione più veloce

HMAC3(password)

che dà lo stesso risultato. È questo il caso?

    
posta Sjoerd 19.05.2016 - 12:16
fonte

1 risposta

2

Sì, ci sono diversi requisiti per una funzione hash iterativa:

  • Non dovrebbe essere possibile fare alcuna precomputazione, come usare le tabelle arcobaleno.
  • L'implementazione dovrebbe evitare l'esecuzione di cicli o punti fissi nella funzione di hash.
  • L'implementazione dovrebbe essere il più veloce possibile, perché è quello che l'utente malintenzionato avrebbe usato.

Specialmente nel punto finale manca il codice di esempio. Il crypto.createHmac(algorithm, salt) dovrebbe davvero essere al di fuori del ciclo. Poiché l'hacker ha molte password con lo stesso sale, può anche piazzare la chiamata di createHmac al di fuori del ciclo della password, ad esempio:

hmac = crypto.createHmac(algorithm, salt)
for (password in allpasswords) {
    var hash = password;
    for(var i=0; i<iterations; ++i) {
        hash = hmac.update(hash).digest('hex');
    }
    ...
}

Ciò conferisce all'utente malintenzionato un vantaggio durante il cracking delle password, che verrebbe evitato se l'HMAC utilizzasse la password anziché il salt come chiave, come fa PBKDF2.

Con implementando il codice specificato in C e facendo alcune ottimizzazioni, sono riuscito a ottenere che fosse 10 volte più veloce rispetto all'implementazione NodeJS originale. Ciò significa che un utente malintenzionato può decifrare le password 10 volte più velocemente di quanto previsto, senza nemmeno utilizzare una GPU o FPGA.

Quindi esiste esiste una funzione che esegue una versione veloce di HMAC(HMAC(HMAC(password))) , semplicemente perché HMAC svolge lo stesso lavoro in ogni iterazione.

Ho scritto un post del blog su questo.

    
risposta data 25.05.2016 - 13:39
fonte

Leggi altre domande sui tag