Il modo migliore per archiviare la password nel database [chiuso]


476

Sto lavorando a un progetto che deve avere l'autenticazione (nome utente e password)

Si collega anche a un database, quindi ho pensato che avrei memorizzato il nome utente e la password lì. Tuttavia, non sembra una buona idea avere password come solo un campo di testo in una tabella seduta sul database.

Sto usando C # e mi collego a un server espresso 2008. Qualcuno può suggerire (con il maggior numero possibile di esempi) quale sarebbe il modo migliore per archiviare questo tipo di dati?

PS Sono aperto all'idea che queste informazioni non vengano archiviate nel database se è possibile fornire una buona ragione


1
Qualunque cosa tu faccia, se vai con la crittografia, non memorizzare la chiave nel codice come menzionato in precedenza. Questa è solo una cattiva pratica.
Woody,

12
"Come si fanno le password, vero?" è una domanda vitale. È un problema difficile e gli errori hanno gravi conseguenze (ricorda cosa è successo a Tesco e LinkedIn). Penso che questa domanda dovrebbe essere riaperta su programmers.stackexchange.com
Colonnello Panic,

2
È meglio attenersi agli standard - vedi en.wikipedia.org/wiki/PBKDF2 Devi solo trovare un'implementazione nella tua lingua
Boris Treukhov,

5
A questa domanda viene ampiamente data risposta nel forum sulla sicurezza: security.stackexchange.com/questions/211/…
gioele,

Risposte:


406

Hai ragione a dire che archiviare la password in un campo di testo semplice è un'idea orribile . Tuttavia, per quanto riguarda la posizione , per la maggior parte dei casi che incontrerai (e onestamente non riesco a pensare a nessun contro-esempio) archiviare la rappresentazione di una password nel database è la cosa giusta da fare. Con la rappresentazione voglio dire che si desidera hash la password utilizzando un sale (che dovrebbe essere diverso per ogni utente) e un algoritmo sicuro 1-way e negozio che , buttando via la password originale. Quindi, quando si desidera verificare una password, si esegue l'hashing del valore (utilizzando lo stesso algoritmo di hash e salt) e lo si confronta con il valore con hash nel database.

Quindi, mentre è una buona cosa che stai pensando a questo ed è una buona domanda, questo è in realtà un duplicato di queste domande (almeno):

Per chiarire un po 'di più il bit salato, il pericolo con il semplice hashing di una password e l'archiviazione è che se un trasgressore ottiene un blocco del database, può comunque utilizzare quelle che sono note come tabelle arcobaleno per essere in grado di "decrittografare" il password (almeno quelle visualizzate nella tabella arcobaleno). Per ovviare a questo, gli sviluppatori aggiungono un sale alle password che, se eseguite correttamente, rendono semplicemente impossibile effettuare attacchi arcobaleno. Si noti che un malinteso comune è semplicemente aggiungere la stessa stringa unica e lunga a tutte le password; mentre questo non è orribile , è meglio aggiungere sali unici a ogni password. Leggi questo per di più.


40
Intendevo memorizzare la password nel database anziché archiviarla altrove. Prendere quella frase fuori dal contesto fa sembrare che io stia supportando la memorizzazione di password semplici, se leggi il resto ovviamente non lo faccio.
Paolo Bergantino,

14
Non solo quello che ho detto, l'ho indirizzato a una moltitudine di post che parlano di sali e così via ...
Paolo Bergantino,

1
@Paolo Bergantino: sei sicuro che non ci sia un refuso nel tuo post? Dice "Per la maggior parte dei casi che incontrerai (e onestamente non riesco a pensare a nessun contro-esempio) archiviare la password nel database è la cosa giusta da fare." ??? Sembra contrarre i tuoi commenti
Mitch Wheat,

3
Ciò che Paolo ha detto si contraddice direttamente. Un hash salato di una password non è una password. La memorizzazione di un hash salato della password nel database non sta memorizzando la password nel database. Il corpo della risposta è perfettamente appropriato, ma la sua prima frase è estremamente fuorviante.
Robert Rossney,

40
@Robert: Si sta avvicinando pericolosamente a un gioco di semantica meschina, ma lo risolverò comunque ...
Paolo Bergantino,

54

Sfondo Non hai mai ... davvero ... bisogno di conoscere la password dell'utente. Vuoi solo verificare che un utente in arrivo conosca la password di un account.

Hash It: memorizza le password degli utenti con hash (crittografia unidirezionale) tramite una forte funzione hash. Una ricerca per "c # crittografare le password" fornisce un sacco di esempi.

Vedi il creatore di hash SHA1 online per avere un'idea di ciò che produce una funzione di hash (ma non usare SHA1 come funzione di hash, usa qualcosa di più forte come SHA256).

Ora, una password con hash significa che tu (e i ladri di database) non dovresti essere in grado di invertire tale hash nella password originale.

Come usarlo: Ma, dici, come posso usare questa password schiacciata memorizzata nel database?

Quando l'utente accede, ti consegneranno il nome utente e la password (nel suo testo originale) Basta usare lo stesso codice hash per eseguire l'hashing della password digitata per ottenere la versione memorizzata.

Quindi, confronta le due password con hash (hash del database per nome utente e password digitata e con hash). Puoi stabilire se "ciò che hanno digitato" corrisponde "a ciò che l'utente originale ha inserito per la password" confrontando gli hash.

Credito extra:

Domanda: se avessi il tuo database, non potrei semplicemente prendere un cracker come John lo Squartatore e iniziare a fare hash fino a quando non trovo corrispondenze con le tue password memorizzate e con hash? (dato che gli utenti scelgono comunque parole brevi del dizionario ... dovrebbe essere facile)

Risposta: Sì ... sì, possono.

Quindi, dovresti "salare" le tue password. Vedi l' articolo di Wikipedia sul sale

Vedi l' esempio C # "Come eseguire il hash dei dati con salt"


14
Bel post, tranne una cosa: md5 e sha1 sono stati entrambi rotti. Probabilmente dovresti scegliere un algoritmo più potente, come forse la famiglia SHA2.
Paolo Bergantino,

3
Grazie Paolo - hai ragione. Poiché l'uso di SHA2 è facile come usare MD5 e SHA1, utilizzare l'algoritmo di hash più potente.
joej,

5
SHA-1 non è stato rotto. Ma per parafase Bruce Schneier: cammina, non correre, verso SHA-2.
Ian Boyd,

3
"Quindi, dovresti 'salare' le tue password" ... Ma il sale è di solito memorizzato nel database insieme alla password, quindi come può essere d'aiuto? L'attaccante deve semplicemente aggiungere il sale alle frasi di attacco del dizionario contro cui sta testando. In che modo è più sicuro se non rivelare password duplicate?
trusktr,

4
@joej "Non hai mai ... davvero ... bisogno di conoscere la password dell'utente" - è un presupposto molto miope. Esistono molti tipi di applicazioni in cui è davvero necessaria la memorizzazione di una password che può essere recuperata. Ad esempio, un'applicazione che deve accedere frequentemente a un altro sistema con credenziali archiviate, fornite e aggiornate da un utente.
Francisco Zarabozo,

29

Come hash salato indurito dalle chiavi, usando un algoritmo sicuro come sha-512.


6
Secondo me, dovresti sempre usare algoritmi lenti (come Blowfish, ad esempio) per memorizzare le password. Questa risposta è una risposta molto migliore: security.stackexchange.com/questions/211/… . Mettilo qui, perché questa pagina appare ancora in alto nei risultati di ricerca.
Dynom,

2
Seguire questo consiglio per l'archiviazione della password lo farebbe terribilmente sbagliato.
mlissner,

27

La migliore pratica di sicurezza non è di memorizzare la password (nemmeno crittografata), ma di archiviare l'hash salato (con un unico sale per password) della password crittografata.

In questo modo è (praticamente) impossibile recuperare una password in chiaro.


11
Wayne, salando prima di calcolare l'hash, il tavolo arcobaleno viene efficacemente sconfitto, a condizione che il sale abbia dimensioni sufficienti.
Mike Rosenblum,

12
@Wayne Hartman: Non così. Se il valore del sale è esposto, è necessario generare una nuova tabella arcobaleno per quel valore del sale specifico. Il punto di una tabella arcobaleno è avere i valori di hash calcolati in anticipo. E nessuno avrà un tavolo arcobaleno per il suo sale specifico.
Ian Boyd,

10

Consiglio vivamente di leggere gli articoli Basta con The Rainbow Tables: cosa devi sapere sugli schemi di password sicure [link morto, copia nell'archivio Internet ] e su come archiviare in modo sicuro una password .

Molti programmatori, me compreso, pensano di capire sicurezza e hash. Purtroppo la maggior parte di noi non lo fa.


1
@Johan Sembra che il collegamento sia ora interrotto, il che è un peccato. Ecco un'alternativa codahale.com/how-to-safely-store-a-password
zebrabox

6

Potrei essere leggermente fuori tema poiché hai menzionato la necessità di un nome utente e una password e la mia comprensione del problema non è certamente la migliore, ma vale la pena prendere in considerazione OpenID?

Se usi OpenID, non finirai per archiviare alcuna credenziale se capisco correttamente la tecnologia e gli utenti possono utilizzare le credenziali che già possiedono, evitando la necessità di creare una nuova identità specifica per la tua applicazione.

Potrebbe non essere adatto se l'applicazione in questione è puramente per uso interno

RPX offre un modo semplice per integrare il supporto OpenID in un'applicazione.


Concordo sul fatto che openID sormonta le persone, ma per questa applicazione si tratta di un database interno per un'azienda che dubito che vorrebbero che entrasse qualsiasi persona anziana che accede. anche l'accesso al web non è necessario per il corretto funzionamento di questa app, quindi non vorrei richiederlo.
Crash893,

3

Nel tuo scenario, puoi dare un'occhiata all'appartenenza ad asp.net, è buona norma archiviare la password dell'utente come stringa con hash nel database. è possibile autenticare l'utente confrontando la password in arrivo con hash con quella memorizzata nel database.

Tutto è stato creato per questo scopo, controlla l' appartenenza ad asp.net


1

Vorrei MD5 / SHA1 la password se non è necessario essere in grado di invertire l'hash. Quando gli utenti effettuano l'accesso, puoi semplicemente crittografare la password fornita e confrontarla con l'hash. Le collisioni tra hash sono quasi impossibili in questo caso, a meno che qualcuno non abbia accesso al database e non veda un hash per il quale hanno già una collisione.


2
Non userei
zebrabox

3
In realtà, non è così rotto. Quello che possono fare è trovare lo stesso valore di hash per due file diversi. Quello che non possono fare è invertire MD5 e ottenere una password funzionante.
waiwai933,

2
Beh, non sarebbe stato rotto anche allora? Basta inserire l'altra password che genera lo stesso hash e ci si trova. Non è necessario conoscere la password originale. Il modo per risolvere questo problema è se salate la password prima dell'hash.
mjuarez,

2
@mjuarez se aggiungi un salt alla password prima di usare MD5 la collisione non ha importanza perché non puoi usare l'altra password
WiiMaxx
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.