Un ingenuo sviluppatore potrebbe memorizzare direttamente una password nel database, che verrebbe poi confrontata direttamente con la password inviata da un client. Uno sviluppatore più attento alla sicurezza potrebbe invece archiviare solo il hash della password nel database e quindi confrontare l'hash della password dal client. Ma la maggior parte delle persone usa le stesse poche password per i propri account. Pertanto, un sito che richiede un indirizzo email e una password per un account / accesso può quindi avere accesso a tutti gli altri siti per i quali l'utente ha fornito la stessa email + password.
E se il cliente stesse creando l'hash stesso? In questo caso, l'hash verrebbe inviato al server, ma ancora una volta non importa - se so quale hash usi per accedere a google.com, l'hash sarà lo stesso per amazon.com (assumendo lo stesso algoritmo). Che ne dici di accodare una stringa dal server alla password, hashing allora ? Esempio:
- Vado su amazon.com e ho chiesto le mie credenziali
- Con la pagina di login, amazon invia un guid: 'cdfefe81-d466-49a6-acea-140fa52c0901' (questo può essere associato con l'account utente, o semplicemente avere 1 per tutto di amazon)
- Inserisco la mia password, 'safe_password'
- Il client aggiunge il guid per creare 'safe_passwordcdfefe81-d466-49a6-acea-140fa52c0901'
- Questo è un hash con qualsiasi algoritmo di hash appropriato e quindi inviato al server. All'interno del server, l'hash viene re-hash (con un salt) e confrontato con l'hash nel database per l'autenticazione.
Il vantaggio di questo flusso consente a un utente di utilizzare password uguali o simili per più server e fintanto che tutti i client seguono questo schema, nessun server potrebbe mai conoscere la password effettiva dell'utente, anche se tale server è stato compromesso.
Modifica
Per chiarire, l'obiettivo è proteggere la password dell'utente, supponendo che un server sia completamente compromesso. Se eseguo un sito che richiede il login, ricevendo un hash salato dal client (dove fornisco il salt), anche se un utente malintenzionato ha accesso a tutti i dati sul lato server, non essere mai in grado di trovare la password originale dell'utente, assumendo un buon algoritmo di hashing, che limiti significativamente il potenziale impatto per gli utenti di una violazione della sicurezza.
Un'altra applicazione sarebbe numeri di carte di credito, che sono molto simili alle password. Immagina questo scenario: sono responsabile della convalida dei numeri di carta di credito di Visa per l'approvazione delle accuse. Amazon vuole usare il mio servizio, così come ogni altro importante venditore al mondo. Così dico ad Amazon "Non autenticherò alcuna carta di credito direttamente da un numero, ma ti chiederò di inviarmi una versione hash di una stringa, e visto che ti sei registrato come venditore, qui è un GUID che verrà assegnato al tuo account ". La stringa sarebbe qualcosa sulla falsariga di <cc#>:<expiration>:<GUID supplied *to Amazon* by Visa>
.
Quindi questo intero flusso:
- Amazon desidera elaborare CC, richiede GUID da Visa
- Visa genera GUID, invia ad Amazon e associa il GUID all'account
- Amazon invia GUID con la pagina di input della carta di credito all'acquirente
- Sul lato client, dopo aver inserito le informazioni CC, questa informazione non viene mai inviata ad Amazon unhashed , invece, il client costruisce la stringa come descritto sopra, la hash e invia l'hash risultante ad Amazon.
- Amazon vuole consentire ordini ripetuti, quindi memorizza questo hash nel loro database.
- Per l'autenticazione, Amazon utilizza il modello di autenticazione S2S esistente per dimostrare che sono Amazon.com e invia l'hash dal client, insieme al nome, all'indirizzo, ecc. dell'acquirente
- Visa riceve l'hash, controlla il GUID di Amazon e trova tutte le carte di proprietà dell'acquirente specificato. Per ogni carta dell'acquirente, Visa ricostruisce e restituisce il numero della carta + data di scadenza + Amazon GUID e confronta l'hash con quanto ricevuto da Amazon.
- Visa trova una corrispondenza, dice che Amazon ha il diritto di caricare questa carta e Amazon invia una conferma di detto addebito.
Dato questo flusso, anche se dovessi accedere a tutti i database, server, hard disk, email, traffico in entrata, ecc. di Amazon.com, vorrei mai conoscere il numero della carta di credito dell'utente . Il maggior danno che potrei eventualmente infliggere sarebbe se potessi fare lo spoofing di essere un server Amazon.com, potrei essere in grado di caricare l'utente per conto di Amazon.com, ma presumibilmente questo andrebbe nell'account di Amazon.com, quindi non lo farei probabilmente ne beneficeranno affatto. In una situazione ideale, questo flusso sarebbe parte della logica SSL, in modo tale che solo il sito che implementa qualcosa di questa natura riceve il simbolo di blocco nei browser client (non l'ha pensato interamente, ma sembra plausibile)