Domanda:
Come conservare il sale?
George
2012-07-20 11:28:12 UTC
view on stackexchange narkive permalink

Se prevedi di memorizzare la password dell'utente in modo sicuro, devi eseguire almeno quanto segue:

  $ pwd = hash (hash ($ password) + salt)  

Quindi, memorizzi $ pwd nel tuo sistema invece della vera password. Ho visto alcuni casi in cui $ pwd contiene il salt stesso.

Mi chiedo se il sale debba essere conservato separatamente, o va bene se un l'attaccante ottiene il valore hash e il sale contemporaneamente. Perché?

Bene, una cosa da considerare con i sali. Se riesci a mantenerli segreti e gli hash della tua password vengono trapelati, diventa completamente impossibile (probabilmente) recuperare una password, anche con 10.000 schede grafiche che la forzano
AiliarbjvbCMT That's **not** the purpose of a salt, and it's nearly impossible to keep salts hidden anyway!
@Polynomial Bene, qualcosa da considerare. Ho un sistema di autenticazione che utilizza due sali per ciascuna password, uno generato casualmente e memorizzato nel database e uno globale per il sito Web e memorizzato nel codice. Il mio obiettivo era fare in modo che, anche se il database fosse trapelato, non fosse ancora possibile falsificare un cookie di accesso o forzare la password.
AilicrindwCMT The second salt is called a [pepper](http://security.stackexchange.com/questions/3272/password-hashing-add-salt-pepper-or-is-salt-enough), which protects you from attackers that only have access to the database. It's useful, but since you're using parameterised queries (you *are* using them, right?) SQL injection isn't a problem, so that model of attacker is much less likely.
Eh, non sapevo che ci fosse un nome per quello, @Polynomial. E sono abbastanza sicuro che il mio database sia sicuro, ma nel caso non lo fosse. (MongoDB). Immagino che non possa far male e non sia così difficile da implementare
Perdona la mia ignoranza, ma è davvero necessario l'hash della password _prima_ di aggiungere il sale? Se hai un buon algoritmo di hashing, non dovrebbe fare la differenza, giusto?
Che dire di $ pwd = hash (hash ($ password) + nome utente)?
@X-Zero Non dovrebbe esserci alcuna differenza e rende le cose più scomode quando si utilizza un KDF adattivo.
@SilverViper Questa è una cattiva idea. Fornisce a un utente malintenzionato il sale, consentendo loro di calcolare una tabella arcobaleno in anticipo, prima di violare apertamente il database. In una situazione del genere, l'attaccante può accedere immediatamente dopo l'attacco e non hai tempo per reagire. Vedi la mia risposta per una spiegazione più dettagliata di questo problema.
+1 for using salts, which is more than big websites seem to do usually.
@JonasWielicki Sì. Alcuni addirittura archiviano in testo normale. Vedere [Plaintext Offenders] (http://plaintextoffenders.com/) per esempi. Un'altra grande azienda, non elencata lì, è Tesco.
Perché conserveresti un sale? Se potessi calcolarlo usando le credenziali in qualche modo .. come `$ salt = base64_encode ($ username. $ Password);` allora non devi salvarlo e se il nome utente e la password sono corretti, corrisponderanno anche il sale.
@matejkramny È esattamente equivalente a usare il nome utente come salt, e male per lo stesso motivo: se l'attaccante conosce un nome utente in cui vuole entrare, può semplicemente precalcolare gli hash per quel nome utente. Includere la password nel sale non cambia nulla. Per impedire loro di precalcolare gli hash, il sale deve essere memorizzato nel database, quindi non possono ottenerlo prima di ottenere gli hash stessi, il che significa che hanno bisogno di molto tempo per rompere gli hash * dopo * che hanno compromesso il database, il che ti dà la possibilità di cambiare le password prima che ottengano l'accesso.
//, Quali contenitori stai usando?Stai usando iodato o non iodato?Potresti finire con un sale avvelenato, quindi evita i contenitori di metallo, perché il sale rilascia metalli e / o elementi dal metallo.A prescindere, non è necessario utilizzare un salva-cibo, perché il sale non irrancidirà anche se esposto all'aria.Per grandi quantità, consiglio di raccogliere il sale in sacchetti di plastica pesanti da un gallone.Quindi puoi mettere i sacchetti in un secchio da 5 galloni per uso alimentare.Per tutti voi prepper là fuori, può essere usato come oggetto di scambio nel momento del bisogno.
//, https://selfreliantschool.com/how-and-why-to-store-salt
Sei risposte:
Polynomial
2012-07-20 19:23:55 UTC
view on stackexchange narkive permalink

TL; DR: puoi memorizzare il sale in testo normale senza alcuna forma di offuscamento o crittografia, ma non darlo semplicemente a chiunque lo desideri.


Il motivo per cui utilizziamo i sali è per fermare gli attacchi precalcolo, come tabelle arcobaleno. Questi attacchi comportano la creazione di un database di hash e dei relativi testi in chiaro, in modo che gli hash possano essere cercati e convertiti immediatamente in testo normale.

Ad esempio *:

  86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 ae9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98 b84a516841ba77a5b4648de2cd0dfcb30ea46dbb4 c ... 948291f2d6da8e32b007d5270a0a5d094a455a02 ZZZZZX151bfc7ba4995bfa22c723ebe7921b6ddc6961bc ZZZZZY18f30f1ba4c62e2b460e693306b39a0de27d747c ZZZZZZ  

la maggior parte delle tabelle includono anche un elenco di password comuni:

  5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8 passworde38ad214943daad1d64c102faec29de4afe9da3d password1b7a875fc1ea228b9061041b7cec4bd3c52ab3ce3 letmein5cec175b165e3d5e62c9e13ce848ef6feac81bff qwerty123  

* Sto usando SHA-1 qui come esempio, ma spiegherò perché questa è una cattiva idea in seguito.

Quindi, se l'hash della mia password è 9272d183efd235a6803f595e19616c348c275055 , sarebbe estremamente facile cercarlo in un database a e scoprire che il testo in chiaro è bacon4 . Quindi, invece di passare qualche ora a decifrare l'hash (ok, in questo caso sarebbero pochi minuti su una GPU decente, ma ne parleremo più avanti) ottieni il risultato istantaneamente .

Ovviamente questo è un male per la sicurezza! Quindi, usiamo un sale. Un salt è un token univoco casuale memorizzato con ciascuna password. Supponiamo che il sale sia 5aP3v * 4! 1bN<x4i&3 e l'hash sia 9537340ced96de413e8534b542f38089c65edff3 . Ora il tuo database di password è inutile, perché nessuno ha tabelle arcobaleno che includono quell'hash. È computazionalmente impossibile generare tabelle arcobaleno per ogni possibile sale.

Quindi ora abbiamo costretto i cattivi a ricominciare a rompere gli hash. In questo caso, sarebbe abbastanza facile da decifrare dato che ho usato una password sbagliata, ma è comunque meglio che lui riesca a cercarla in un decimo di secondo!

Ora, visto che l'obiettivo of the salt serve solo per impedire la creazione di database pre-generati, non ha bisogno di essere crittografato o nascosto nel database. Puoi memorizzarlo come testo normale. L'obiettivo è costringere l'attaccante a dover decifrare gli hash una volta ottenuto il database, invece di poterli cercare tutti in una tabella arcobaleno.

Tuttavia, c'è un avvertimento. Se l'aggressore può accedere silenziosamente a un salt prima di entrare nel tuo database, ad es. attraverso una sceneggiatura che offre il sale a chiunque lo richieda, può produrre una tavola arcobaleno per quel sale il più facilmente possibile se non ce ne fosse uno. Ciò significa che potrebbe prendere silenziosamente il sale del tuo account amministratore e produrre una bella grande tabella arcobaleno, quindi hackerare il tuo database e accedere immediatamente come amministratore. Questo non ti dà il tempo di individuare che si è verificata una violazione e non c'è tempo per agire per prevenire danni, ad es. cambiare la password dell'amministratore / bloccare gli account privilegiati. Questo non significa che dovresti oscurare i tuoi sali o tentare di crittografarli, significa solo che dovresti progettare il tuo sistema in modo tale che l'unico modo in cui possono arrivare ai sali è entrare nel database.

Un'altra idea da considerare è un pepe. Un pepe è un secondo sale che è costante tra le singole password, ma non memorizzato nel database. Potremmo implementarlo come H (salt + password + pepper) o KDF (password + pepper, salt) per una funzione di derivazione della chiave - ne parleremo dopo. Tale valore potrebbe essere memorizzato nel codice. Ciò significa che l'attaccante deve avere accesso sia al database che al codice sorgente (o ai binari della webapp nel caso di ASP .NET, CGI, ecc.) Per tentare di violare gli hash. Questa idea dovrebbe essere utilizzata solo per integrare altre misure di sicurezza. Un peperoncino è utile quando sei preoccupato per gli attacchi SQL injection, in cui l'autore dell'attacco ha accesso solo al database, ma questo modello sta (lentamente) diventando meno comune man mano che le persone passano alle query parametrizzate. stai utilizzando query con parametri, giusto? Alcuni sostengono che un peperone costituisca sicurezza attraverso l'oscurità, dal momento che stai solo oscurando il pepe, il che è in qualche modo vero, ma non è per dire che l'idea sia priva di merito.

Ora siamo a una situazione dove l'attaccante può forzare ogni singolo hash della password, ma non può più cercare tutti gli hash in una tabella arcobaleno e recuperare immediatamente le password in chiaro. Quindi, come possiamo prevenire gli attacchi di forza bruta adesso?

Le moderne schede grafiche includono GPU con centinaia di core. Ogni core è molto bravo in matematica, ma non molto bravo nel processo decisionale. Può eseguire miliardi di calcoli al secondo, ma è piuttosto terribile quando si eseguono operazioni che richiedono ramificazioni complesse. Gli algoritmi di hash crittografici rientrano nel primo tipo di calcolo. In quanto tali, framework come OpenCL e CUDA possono essere utilizzati per accelerare notevolmente il funzionamento degli algoritmi hash. Esegui oclHashcat con una scheda grafica decente e puoi calcolare un eccesso di 10.000.000.000 di hash MD5 al secondo. Anche SHA-1 non è molto più lento. Ci sono persone là fuori con piattaforme di cracking per GPU dedicate contenenti 6 o più schede grafiche di fascia alta, con una velocità di cracking di oltre 50 miliardi di hash al secondo per MD5. Mettiamolo nel contesto: un sistema del genere può forzare brutemente una password alfanumerica di 8 caratteri in meno di 4 minuti .

Chiaramente hash come MD5 e SHA-1 sono troppo veloci per questo tipo di situazione. Un approccio a ciò consiste nell'eseguire migliaia di iterazioni di un algoritmo di hash crittografico:

  hash = H (H (H (H (H (H (H (H (H (H (H ( H (H (H (H (... H (password + salt) + salt) + salt) ...)  

Questo rallenta il calcolo dell'hash, ma non è perfetto . Alcuni sostengono l'utilizzo degli hash della famiglia SHA-2, ma questo non fornisce molta sicurezza aggiuntiva. Un approccio più solido consiste nell'usare una funzione di derivazione chiave con un fattore di lavoro. Queste funzioni accettano una password, una sale e un fattore di lavoro. Il fattore di lavoro è un modo per adattare la velocità dell'algoritmo ai requisiti hardware e di sicurezza:

  hash = KDF (password, salt, workFactor)  

I due KDF più popolari sono PBKDF2 e bcrypt. PBKDF2 funziona eseguendo iterazioni di un HMAC con chiave (sebbene possa utilizzare cifrature a blocchi) e bcrypt calcola e combina un gran numero di blocchi di testo cifrato dal cifrario a blocchi Blowfish. Entrambi fanno più o meno lo stesso lavoro. Una variante più recente di bcrypt chiamata scrypt funziona secondo lo stesso principio, ma introduce un'operazione che richiede molta memoria che rende il cracking su GPU e aziende FPGA completamente impossibili, a causa della larghezza di banda della memoria restrizioni.


Aggiornamento: a partire da gennaio 2017, l'algoritmo di hashing all'avanguardia scelto è Argon2, che ha vinto la competizione per l'hashing delle password.


Si spera che questo ti dia una buona panoramica dei problemi che dobbiamo affrontare durante la memorizzazione delle password e risponda alla tua domanda sulla conservazione del sale. Consiglio vivamente di controllare i "link di interesse" in fondo alla risposta di Jacco per ulteriori letture, così come questi link:

+1, Amen. Vorrei che fossimo in grado di creare un indice / directory che punti alle buone risposte a domande comuni / popolari come questa. Ancor di più, perché le domande comuni / popolari attirano regolarmente anche risposte abbastanza insicure.
L'altro giorno stavo leggendo di [Scrypt] (http://en.wikipedia.org/wiki/Scrypt), che è un KDF che mira ad essere più costoso dal punto di vista computazionale di Bcrypt e PBKDF2. Potrebbe essere un'altra opzione da considerare.
AiliwcwlqdCMT I mentioned scrypt in the second-to-last paragraph. The only downside with Scrypt is that there aren't as many libraries available, and there hasn't been much study of it. Right now I'd suggest bcrypt, since FPGA-based cracking engines are not a security concern for most people, but when scrypt has been studied carefully by a few cryptographers I'd be happy to tell people to use it instead.
Dai anche un'occhiata a https://wiki.mozilla.org/Identity/CryptoIdeas/01-PBKDF-scrypt
@Polynomial potrebbe anche aggiungere un collegamento a http://stackoverflow.com/questions/1645161/salt-generation-and-open-source-software/1645190#1645190?
+1 per il collegamento alla sezione ** Link di interesse ** della risposta di @Jacco's.
Tuttavia, se si implementa un fattore come il codice sms, è anche possibile memorizzare le password in chiaro .. perché devono comunque passare attraverso il codice sms.
@matejkramny No. Il problema principale è che gli utenti riutilizzeranno SEMPRE le proprie password per altri siti. Hai il dovere di diligenza di proteggere le password che ti vengono fornite.
Qual è il motivo per aggiungere sempre di nuovo il sale quando si esegue nuovamente l'hashing della password?
@cooky451 Non sono sicuro di quello che stai chiedendo, ma suggerisco di creare una nuova domanda.
bcrypt sembra anche essere il più facile da usare dal punto di vista di un programmatore. Non devi nemmeno inventarti un salt perché la libreria crittografica lo farà per te, poiché l'output include il sale (è nella forma `$ $ $ <22 caratteri salt> <31 caratteri hash> "). Quindi tutte le informazioni necessarie sono memorizzate in quello che puoi pensare come l'hash. Non potrebbe essere più facile di così (pur essendo altamente sicuro).
Solo per enfasi: assicurati di usare un *** salt *** diverso per ogni password!Se si utilizza lo stesso salt per ogni password, la complessità di calcolo dell'algoritmo di forza bruta viene notevolmente ridotta.Inoltre, un utente malintenzionato potrebbe vedere quali utenti utilizzano la stessa password semplicemente confrontando gli hash, il che potrebbe avere un effetto di anonimizzazione sugli utenti che riutilizzano le password su più account.
Bouncycastle ha un'implementazione scrypt.
Davvero una buona risposta.Ma ancora non hai risposto alla domanda "dove conservo il sale casuale"?Hai bisogno di quel sale casuale per verificare se la password inserita è corretta ... mi sbaglio?
"Ciò significa che l'aggressore deve avere accesso sia al database che al codice sorgente" - non è vero per l'ultima parte.In molti (se non nella maggior parte) casi le stringhe non sono crittografate.Un hacker può facilmente caricare un eseguibile in un editor esadecimale e vedere la maggior parte delle stringhe.Possono anche passare attraverso il codice assembly per leggere anche i valori.In molti casi il codice sorgente non è richiesto e quindi qualsiasi valore sale e pepe memorizzato / calcolato sul lato client (ad es. App desktop) non è impossibile;solo difficile.;) Non memorizzarli come testo normale.Offuscare questi tipi di stringhe per renderlo più difficile.
@JamesWilkins Sì, stavo pensando alle applicazioni web PHP / Python quando ho scritto questo.Modificherò per riflettere il caso più diversificato in cui l'app Web è un file binario .NET o CGI.
-1 - troppo testo e in realtà non risponde alla domanda su dove conservare il sale (anche se ho smesso di leggere a metà perché il testo è irrilevante per la domanda effettiva)
Jacco
2012-07-20 12:37:05 UTC
view on stackexchange narkive permalink

Un salt non è pensato per essere segreto, invece, un salt "funziona" assicurandosi che l'hash risulti univoco per ogni istanza utilizzata. Questo viene fatto scegliendo un valore salt casuale diverso per ogni hash calcolato.

L'intenzione del sale non è compromessa quando è nota; l'attaccante deve ancora attaccare ogni hash separatamente. Pertanto, puoi semplicemente memorizzare il salt insieme alla password con hash.

Link di interesse :
Come eseguire l'hashing sicuro delle password?
L'hashing delle password aggiunge sale + pepe o il sale è sufficiente?
Salt Generation e software open source

Keep in mind that if the salt is leaked (e.g. through a flaw in your code) the attacker can build a rainbow table for that salt ahead of time. This makes it difficult for you to take preventative measures if someone steals your hashes later, because they can immediately crack the password (they already have the rainbow table!) and access the account.
@Polynomial Hai fatto un'ottima osservazione. Forse vorresti scrivere una risposta che copra ciò che hai affermato? Lo voterei sicuramente a favore, ed è molto più facile da leggere in questo modo.
@Terry Chia: Il prepending è più comune.
Accanto al * hash, salato, password *.
@Polynomial dove conservi il sale allora?Sembra che se l'aggressore trova il sale può entrare nel database?
lxgr
2012-07-20 12:38:24 UTC
view on stackexchange narkive permalink

Il sale può e deve essere conservato accanto alla password salata e con hash. Inoltre, il salt dovrebbe essere univoco per ogni password.

Il suo scopo è rendere impossibile attaccare un database di password trapelato utilizzando tabelle precalcolate di coppie password-hash.

Funziona perché il sale diventa noto all'aggressore solo non appena ottiene le password effettive (rinforzate); rendendo così impossibile qualsiasi attacco precalcolato. (Se non usi un salt univoco per password, ma uno globale, le tabelle precalcolate potrebbero comunque essere utilizzate, anche se dovrebbero essere precalcolate specificamente per il salt della tua applicazione.)

Quando memorizzi il sale da qualche altra parte rispetto alla password, potresti ottenere un po 'di sicurezza aggiuntiva, ma quasi vanifica lo scopo: ogni volta che vuoi convalidare una password, hai bisogno sia del sale che della password con hash, quindi devono essere molto "vicini" (in senso architettonico) comunque.

Tgr
2012-07-20 22:35:16 UTC
view on stackexchange narkive permalink

La memorizzazione dei sali separatamente offre un po 'di sicurezza in più, ma non molto: dopotutto, il database dovrebbe essere il luogo più protetto dell'applicazione, quindi se l'aggressore ha accesso al database, è probabile che abbia accesso a qualsiasi altro dato . D'altra parte, hai bisogno di un sale diverso per ogni utente, il che significa che hai bisogno di molto sale - semplicemente non è fattibile memorizzarlo fuori dal database.

Esiste la pratica di usare un secondo pezzo di sale (a volte chiamato pepe) che è lo stesso per tutti gli utenti e lo memorizza al di fuori del database (magari in una variabile di ambiente o in una sorta di file di configurazione), in modo che l'attaccante non possa accedervi con un semplice SQL iniezione. Questo aggiunge un po 'di sicurezza, ma come detto sopra, non aspettarti troppo da esso e usa bcrypt o qualche altro metodo di hashing lento per difenderti dai sali rubati.

user7610
2012-07-20 20:58:26 UTC
view on stackexchange narkive permalink

Vorrei rivolgere la vostra attenzione a un articolo interessante su questo tema dal titolo Archiviare le password in modo sicuro

TL; DR

L'autore dell'articolo spiega la salatura e il pepe. Inoltre, sostiene che in realtà non si desidera utilizzare una funzione di hashing crittografico per memorizzare le password. I due tratti principali di un hash sono che

  1. dovrebbe essere unidirezionale e.
  2. dovrebbe essere economico da calcolare.

Ovviamente questi requisiti vanno contro l'altro. Quindi viene fatto un compromesso. Non vuoi che l'attaccante sia in grado di calcolare i propri tentativi di forza bruta a basso costo. Pertanto, per una maggiore sicurezza, è effettivamente necessaria una funzione di derivazione della chiave, qualcosa che sia unidirezionale e che richieda più tempo per il calcolo (ad es. 0,1 s).

Esistono schemi / implementazioni su come farlo, le cosiddette funzioni Adaptive Key Derivation che sono ben studiate e ritenute sicure (tre nomi di autori: PBKDF2, bcrypt, scrypt )

A questo punto la tua risposta non ha davvero portato nulla al tavolo, quindi probabilmente dovresti semplicemente collegare l'articolo in un commento. Tuttavia è un bell'articolo, molto approfondito e copre tutte le basi. Terrò un segnalibro per riferimento futuro!
Nice article! As far as I know, PBKDF2 is an Adaptive Key Derivation Function, but BCrypt and SCrypt are not; they are adaptive cost hashing algorithms. (The difference is subtle, but real).
Polinomio: hai ragione. Ero così ansioso di pubblicare l'articolo (l'avevo tra i miei segnalibri e mi sono emozionato che fosse finalmente arrivato il momento) che ho appena sfogliato la tua risposta e ho perso completamente l'ultimo paragrafo. scusate
Andrew Smith
2012-07-21 00:41:49 UTC
view on stackexchange narkive permalink

Bene, separa l'hashish dal sale in due scatole diverse: spero che tu abbia capito la risposta corretta. E assicurati di avere la stessa quantità di entrambi, come sale a 256 bit, hash a 256 bit, puoi aumentare la sicurezza se usi un semplice server salt isolato.

Perché conservare hashish e sale in luoghi diversi?
Vedi ad es. http://security.stackexchange.com/a/17449/5501
-1 "un hash a 256 bit" non ti fa comprare niente di peso qui. L'algoritmo deve essere lento. Separando le diverse scatole di hashish e acros di sale, si crea una gamma completamente nuova di problemi, basta attenersi alle migliori pratiche.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...