C'è un difetto molto significativo (supponendo che intendessi lo standard cryptogrfahic salt che è necessariamente archiviato nel database):
salt = md5(Hashed Username ++ db_ID ++ Password)
Con i sali normali sono archiviati nel database e probabilmente il nome utente è memorizzato in una colonna separata, quindi se un amministratore malintenzionato o un iniettore SQL riesce a mettere le mani sul DB, possono usare solo i sali MD5 memorizzati nella forza bruta le password. Dato che MD5 è un sale molto debole, a meno che la password non sia un'entropia molto alta, una GPU può craccarla provando diversi miliardi di password al secondo [1] .
Tuttavia, potresti aver inteso che il tuo database memorizza solo username
e multi_round_hash_sha512_hash
; in particolare non memorizzando il nome utente derivato 'salt' come nell'esempio seguente (dove ++
è concatenazione):
db_id = uuid(username);
username_derived_salt = md5(username ++ db_id ++ password);
# this salt not stored in DB
multi_round_hash = password;
for(i=0; i < rounds; i++) {
multi_round_hash = sha512(multi_round_hash ++ username_derived_salt);
}
In questo caso, questo non è un difetto, anche se è fondamentalmente equivalente all'utilizzo di un nome utente stesso come un sale con un po 'di oscurità su di esso.
Inoltre, l'utilizzo di un numero dinamico di round che aumenta nel tempo sembra inutilmente complicato e non vedo il vantaggio rispetto a un numero fisso (diciamo 100.000 round, che potresti decidere di aumentare a un certo punto). Prevedo molti problemi di implementazione (i timestamp sono disallineati tra gli utenti, quindi il numero di round è diverso, con un cron job che aggiunge un giro extra agli hash memorizzati ogni giorno - possibili problemi con gli utenti che cercano di effettuare il login intorno a mezzanotte; . Per lo meno memorizzare il numero di cicli con la password hash e test molto accuratamente.
Usare qualcosa come bcrypt / PBKDF sembra molto più semplice.