L'hashing della password di accesso è che si suppone funzioni
Si noti che in tutti i frammenti, sto escludendo intenzionalmente le funzionalità di sicurezza perché voglio mantenerlo compatto. Non fare affidamento su questi frammenti di codice per qualsiasi cosa.
In usual network applications ,that employ password hashing, is the user password hashed on client side before sending it to the server or is it sent without hashing as encryption of plain text password to the server?
No, è lato server con hash. Si invia la password su testo normale o tramite HTTPS al server. Il server genererà quindi un hash per la password, in questo modo:
public void RegisterAccount(string username, string password, string email)
{
if (!Database.EmailExists(email) && !Database.UsernameExists(username))
{
Database.AddNewUser(username, Hash.GenerateHash(password), email);
}
}
Supponi che Database.AddNewUser(string, string, string);
inserisca il nome utente, la password hash e l'e-mail nel database. L'hash viene generato in base alla password.
Supponiamo che tu inserisca la parola d'ordine "non mi hackerare per favore". bcrypt lo trasformerà in $2a$08$BOHyNdXAVkWOUgPG/hvsjew7ZpngqJIgueY6m76xd4y3UllXUZLBy
, o qualche altra variante basata sul sale. Il database ora assomiglia a questo:
+--------------+--------------------------------------------------------------+--------------------+
| user | password | email |
+--------------+--------------------------------------------------------------+--------------------+
| markbuffalo | $2a$08$BOHyNdXAVkWOUgPG/hvsjew7ZpngqJIgueY6m76xd4y3UllXUZLBy | [email protected] |
+--------------+--------------------------------------------------------------+--------------------+
Normalmente chiamerai il database per leggere la password per quel nome utente. Una volta chiamato il database, si utilizzerà una funzione, ad esempio Hash.ValidateHash()
, per verificare se corrisponde. Se corrisponde, puoi accedere usando quella password non hash.
Perché non puoi semplicemente passare l'hash per accedere?
In alcuni casi molto sfortunati .
The main question I have is if an attacker discovers the hashed passwords then why can't he just send hash to the server to authenticate in case of client side hashing?
Questo è possibile, ma può accadere solo durante le gravi occorrenze di errori epici massivi da parte degli sviluppatori. In effetti, l'ho già visto prima e ti mostrerò come ciò può accadere tramite codice:
public void Login(string username, string password)
{
if (Database.LoginMatches(username, password) ||
Database.LoginMatches(username, Hash.ValidateHash(password)))
{
logMeIn();
}
}
Nel frammento di cui sopra, il login vuole verificare se l'utente ha l'hash o la password che verrà convalidata nell'hash memorizzato nel database. Questo è non il modo corretto per farlo. In effetti, è uno dei peggiori casi di fallimento epico che abbia mai visto in vita mia.
Con questo codice, puoi semplicemente inserire l'hash o la password e accedere. Richiama la tabella precedente. Uno dei seguenti accessi funzionerà correttamente:
-
Login("markbuffalo", "$2a$08$BOHyNdXAVkWOUgPG/hvsjew7ZpngqJIgueY6m76xd4y3UllXUZLBy");
-
Login("markbuffalo", @"don't hack me please");
Questo è l'approccio sbagliato interamente. Non dovrebbe succedere. A. Tutti. Tuttavia, alcuni sviluppatori hanno adottato questo approccio per ragioni che non conosco.
Qual è l'approccio giusto per la convalida dell'hash?
Come Rápli András detto, h(x)
non corrisponde a h(h(x))
. L'approccio giusto è quello di controllare la password in arrivo contro l'hash per vedere se corrispondono. Se non corrispondono, non utilizzare nessuna magia OR
( ||
); semplicemente non permettere loro di accedere.