Quindi mi sono divertito con l'idea di avere valori di sale non deterministici per gli hash.
Lascia che ti spieghi cosa intendo:
Fondamentalmente, ho applicato alcune proprietà da Bitcoin, inclusa una "difficoltà" (ovvero, il valore hash deve iniziare con un certo numero di bit 0) e ho trovato qualcosa che potrebbe essere utilizzato per gli hash delle password.
Il mio algoritmo:
string hashstring=password;
for(int i = 0; i < int.MaxValue; i++)
{
var hash = Hash(hashstring);
hashstring = Convert.ToBase64String(hash);
if(MeetsDifficulty(hash, difficulty))
{
Console.WriteLine("i: "+i);
return hashstring;
}
}
password in questo caso, è qualcosa come password+salt
dove sale è un sale random criptografico standard memorizzato con l'hash. Tuttavia, come puoi vedere, esiste anche un valore i
per quante volte deve essere sottoposto a hash, che non è archiviato insieme all'hash.
In questo modo, devi hash la password un numero di volte finché non trovi qualcosa che soddisfi il livello di difficoltà richiesto. È facile da verificare, ma richiede tempo perché è sconosciuto esattamente quante volte il valore deve essere sottoposto a hash.
Ci sono alcune proprietà interessanti di questo meccanismo:
- Una password errata è leggermente non rilevabile. L'unico modo per sapere che non è corretto è se conosci il livello di difficoltà e trovi un hash che lo soddisfa, ma non corrisponde all'hash
- Probabilmente è abbastanza difficile calcolare tutto questo in parallelo?
- In teoria, è completamente sconosciuto quanto tempo ci vorrà per verificare o calcolare un hash (diverso dalle probabilità)
- Bruteforce sarebbe probabilmente difficile perché ogni password tentata potrebbe comportare una quantità enorme di hash necessari per verificarlo alla difficoltà
Tuttavia, non riesco davvero a trovare un buon uso di queste proprietà. C'è qualche cosa buona per applicare un tale schema o c'è qualcosa che usa un tale schema?
Inoltre, ci sono dei potenziali punti deboli in questo schema di hashing?
Per i miei test, ho usato SHA256 come algoritmo di hashing, ed è diventato piuttosto lento dopo una difficoltà di circa 20 bit di zeri. Tuttavia, questo potrebbe essere facilmente sostituito con l'uso di scrypt, bcrypt o SHA512
Inoltre, un'altra idea è che potresti costruire "velocemente" per verificare gli hash, ma solo quando hai la password corretta. (cambiando il sale se, ad esempio, hai già cancellato il valore X volte e vuoi scegliere come target solo l'hashing del valore Y volte per verificarlo quando viene fornita una password corretta)