La necessità di nascondere il sale per un hash


99

Al lavoro abbiamo due teorie concorrenti per i sali. I prodotti su cui lavoro usano qualcosa come un nome utente o un numero di telefono per salare l'hash. Essenzialmente qualcosa che è diverso per ogni utente ma è prontamente disponibile per noi. L'altro prodotto genera in modo casuale un salt per ogni utente e cambia ogni volta che l'utente cambia la password. Il sale viene quindi crittografato nel database.

La mia domanda è se il secondo approccio è davvero necessario? Posso capire da un punto di vista puramente teorico che è più sicuro del primo approccio, ma che dire da un punto di vista pratico. In questo momento per autenticare un utente, il sale deve essere non crittografato e applicato alle informazioni di accesso.

Dopo averci pensato, non vedo un reale vantaggio in termini di sicurezza da questo approccio. Cambiare il sale da un account all'altro rende ancora estremamente difficile per qualcuno tentare di forzare l'algoritmo di hashing anche se l'aggressore era a conoscenza di come determinare rapidamente cosa fosse per ogni account. Questo presuppone che le password siano sufficientemente forti. (Ovviamente trovare l'hash corretto per un set di password in cui sono tutte due cifre è significativamente più facile che trovare l'hash corretto delle password che sono 8 cifre). Sono sbagliato nella mia logica o c'è qualcosa che mi manca?

EDIT: Ok, ecco il motivo per cui penso che sia davvero discutibile crittografare il sale. (fammi sapere se sono sulla strada giusta).

Per la seguente spiegazione, supponiamo che le password siano sempre 8 caratteri e il salt sia 5 e tutte le password siano composte da lettere minuscole (semplifica la matematica).

Avere un sale diverso per ogni voce significa che non posso usare la stessa tabella arcobaleno (in realtà tecnicamente potrei se ne avessi una di dimensioni sufficienti, ma ignoriamolo per il momento). Questa è la vera chiave del sale da quello che ho capito, perché per rompere ogni account devo reinventare la ruota per così dire per ognuno. Ora, se so come applicare il salt corretto a una password per generare l'hash, lo farei perché un salt estende in realtà solo la lunghezza / complessità della frase con hash. Quindi taglierei il numero di combinazioni possibili che dovrei generare per "sapere" che ho la password + sale da 13 ^ 26 a 8 ^ 26 perché so cos'è il sale. Ora questo lo rende più facile, ma ancora molto difficile.

Quindi sulla crittografia del sale. Se so che il sale è crittografato, non proverei a decrittografarlo (supponendo di sapere che ha un livello sufficiente di crittografia) prima. Lo ignorerei. Invece di cercare di capire come decrittografarlo, tornando all'esempio precedente, genererei semplicemente una tabella arcobaleno più grande contenente tutte le chiavi per 13 ^ 26. Non conoscere il sale mi rallenterebbe sicuramente, ma non credo che aggiungerebbe il compito monumentale di provare prima a decifrare la crittografia del sale. Ecco perché non credo ne valga la pena. Pensieri?

Ecco un collegamento che descrive per quanto tempo le password resisteranno a un attacco di forza bruta: http://www.lockdown.co.uk/?pg=combi


Bella domanda, Kevin, molto tempestiva. Non posso commentare sulla sicurezza, ma sicuramente c'è un calo di prestazioni per tutta questa crittografia e decrittografia.
DOK

Non è necessario ignorare la tabella arcobaleno di dimensioni decenti: quella tabella rende anche discutibile il sale crittografato poiché può decrittografare l'hash salato ed essere utilizzato di nuovo per decrittografare l'hash originale. La buona notizia è che la creazione del tavolo richiederà probabilmente secoli.
tloach

La cosa che mi colpisce è che non sono del tutto certo che un tavolo arcobaleno di quelle dimensioni richiederebbe così tanto tempo per essere creato. È un'idea stravagante, prendi una piattaforma informatica distribuita come Kraken (in realtà è un po 'quello che è) per generarla. Quanto tempo ci vorrà allora?
kemiller2002

3
@Kevin: SHA1 restituisce una stringa esadecimale di 40 caratteri, quindi ci sono 40 ^ 16 possibili valori di ritorno. Supponendo che un singolo computer possa calcolare 1000 hash al secondo, si calcola che 1000000 computer impiegherebbero circa 10 miliardi di anni per generare una tabella arcobaleno in grado di determinare una stringa di quelle dimensioni.
tloach

+1 bella domanda e hai letto bene. Penso che tu abbia la risposta sbagliata a questa domanda. Dovrebbe essere sempre un segreto perché l'hash non può essere rotto fino a quando non viene ottenuto. Dovresti leggere di CWE-760 ( cwe.mitre.org/data/definitions/760.html )
torre

Risposte:


45

La risposta qui è chiedersi da cosa stai veramente cercando di proteggerti? Se qualcuno ha accesso al tuo database, ha accesso ai sali crittografati e probabilmente ha accesso anche al tuo codice. Con tutto ciò potrebbero decifrare i sali crittografati? Se è così, la crittografia è comunque praticamente inutile. Il sale è davvero lì per farlo, quindi non è possibile formare una tabella arcobaleno per decifrare l'intero database delle password in una volta sola se viene violato. Da quel punto di vista, fintanto che ogni sale è unico non c'è differenza, sarebbe necessario un attacco di forza bruta con i tuoi sali o i sali crittografati per ciascuna password individualmente.


Un po 'nuovo a questi concetti. Quindi, potrebbe sembrare una domanda ingenua, ma non sarebbe più facile formare quella tabella arcobaleno conoscendo il sale per ogni password poiché proveresti solo una combinazione per il valore del sale per ogni possibile password?
stdout

la tabella ranbow da diciamo 1000 password comunemente usate lo interromperebbe quasi alla stessa velocità del semplice hashing. L'unico modo in cui funzionerebbe è che se
presumi

100

Non è necessario nascondere un sale.

Per ogni hashish dovrebbe essere usato un sale diverso. In pratica, questo è facile da ottenere ottenendo 8 o più byte dal generatore di numeri casuali di qualità crittografica.

Da una mia precedente risposta :

Salt aiuta a contrastare gli attacchi dei dizionari precalcolati.

Supponiamo che un utente malintenzionato disponga di un elenco di probabili password. Può eseguire l'hash di ciascuno e confrontarlo con l'hash della password della sua vittima e vedere se corrisponde. Se l'elenco è grande, l'operazione potrebbe richiedere molto tempo. Non vuole spendere così tanto tempo sul suo prossimo obiettivo, quindi registra il risultato in un "dizionario" dove un hash punta al suo input corrispondente. Se l'elenco delle password è molto, molto lungo, può utilizzare tecniche come un Rainbow Table per risparmiare spazio.

Tuttavia, supponiamo che il suo prossimo obiettivo abbia salato la loro password. Anche se l'aggressore sa qual è il sale, la sua tabella precalcolata non ha valore: il sale cambia l'hash risultante da ogni password. Deve ripetere l'hash di tutte le password nella sua lista, apponendo il sale del bersaglio all'input. Ogni sale diverso richiede un dizionario diverso e, se vengono utilizzati abbastanza sali, l'attaccante non avrà spazio per memorizzare i dizionari per tutti loro. Lo spazio di trading per risparmiare tempo non è più un'opzione; l'attaccante deve ripiegare sull'hashing di ogni password nella sua lista per ogni bersaglio che vuole attaccare.

Quindi, non è necessario mantenere il segreto del sale. È sufficiente assicurarsi che l'attaccante non disponga di un dizionario precalcolato corrispondente a quel particolare sale.


Dopo averci pensato un po 'di più, mi sono reso conto che ingannare te stesso nel pensare che il sale possa essere nascosto è pericoloso. È molto meglio presumere che il sale non possa essere nascosto e progettare il sistema in modo che sia sicuro nonostante ciò. Fornisco una spiegazione più dettagliata in un'altra risposta.


Tuttavia, recenti raccomandazioni del NIST incoraggiano l'uso di un "sale" segreto aggiuntivo (ho visto altri chiamare questo "pepe" segreto aggiuntivo). Un'ulteriore iterazione della derivazione della chiave può essere eseguita utilizzando questo segreto come sale. Piuttosto che aumentare la forza contro un attacco di ricerca precalcolato, questo round protegge dall'indovinare la password, proprio come il gran numero di iterazioni in una buona funzione di derivazione della chiave. Questo segreto non ha scopo se memorizzato con la password con hash; deve essere gestito come segreto e ciò potrebbe essere difficile in un database di utenti di grandi dimensioni.


1
Nascondere il sale è necessario perché l'hashish non può essere rotto finché non viene ottenuto. Questo è correlato a CWE-760 ( cwe.mitre.org/data/definitions/760.html )
torre

28
@ The Rook - No, stai interpretando male questo problema. Si riferisce all'uso di sali prevedibili. Non dice nulla sul mantenere segreto il sale. In effetti, non puoi davvero mantenere il segreto del sale senza usare un altro segreto ... in tal caso, perché non dovresti usare il secondo segreto come sale? Usare il nome utente come sale è un male perché è probabile che più sistemi condividano lo stesso nome utente, rendendo più utile costruire una tabella per quel particolare sale. I sali casuali sono i migliori, ma non hanno bisogno di essere tenuti segreti.
erickson


1
@erickson, penso che tu stia confondendo la terminologia qui. I sali non ostacolano gli attacchi del dizionario a meno che non siano nascosti. Molti sali vengono conservati apertamente. E se conosci il sale, il tuo attacco al dizionario è rallentato solo dal tempo necessario per aggiungere il sale al termine del dizionario :) I sali impediscono le ricerche sulle tabelle Rainbow .... che sono dannatamente veloci. Se l'aggressore conosce il tuo sale, non sei protetto da un attacco del dizionario. Se l'attaccante non conosce il tuo sale, tuttavia, sei protetto da un attacco del dizionario e deve usare un attacco di forza bruta.
Ultratrunks

4
@Ultratrunks Sì, ho chiarito alcune delle mie risposte su questo argomento, utilizzando il termine "attacchi al dizionario pre-calcolati". Più generale delle tabelle Rainbow, si riferisce a qualsiasi struttura che consenta una ricerca inversa di un testo in chiaro utilizzando il suo hash come chiave. Indipendentemente dai termini che scegli, my spiega esplicitamente che il sale ha lo scopo di sconfiggere le tabelle Rainbow e meccanismi simili. Dovresti sempre presumere che l'aggressore conosca il sale. Se fosse possibile mantenerlo segreto, non sarebbe necessario l'hash della password.
erickson

3

La mia comprensione di "sale" è che rende più difficile il cracking, ma non cerca di nascondere i dati extra. Se stai cercando di ottenere una maggiore sicurezza rendendo il sale "segreto", allora in realtà vuoi solo più bit nelle tue chiavi di crittografia.


3

Il secondo approccio è solo leggermente più sicuro. I sali proteggono gli utenti dagli attacchi del dizionario e dagli attacchi alle tabelle arcobaleno. Rendono più difficile per un aggressore ambizioso compromettere l'intero sistema, ma sono comunque vulnerabili agli attacchi che si concentrano su un utente del sistema. Se utilizzi informazioni pubblicamente disponibili, come un numero di telefono, e l'aggressore ne viene a conoscenza , hai salvato loro un passaggio nel loro attacco. Ovviamente la domanda è discutibile se l'attaccante ottiene l'intero database, i sali e tutto il resto.

EDIT: Dopo aver riletto questa risposta e alcuni commenti, mi viene in mente che parte della confusione potrebbe essere dovuta al fatto che sto solo confrontando i due casi molto specifici presentati nella domanda: random salt vs. sale non casuale. La questione dell'utilizzo di un numero di telefono come sale è discutibile se l'aggressore ottiene l'intero database, non la questione dell'utilizzo di un sale affatto.


Come proteggono dagli attacchi del dizionario?
tloach

Costringendo l'aggressore a creare un nuovo dizionario per ogni combinazione password + salt. Senza sale, un dizionario può essere utilizzato contro l'intera tabella delle password.
Bill the Lizard,

"Ovviamente la domanda è discutibile se l'attaccante ottiene l'intero database, sali e tutto il resto." Non è per questo che il sale è crittografato?
Patrick McElhaney,

1
@ Bill: hai appena descritto un tavolo arcobaleno. Un attacco al dizionario è dove prendo parole normali e cerco di autenticarmi con esse. È una forza bruta con uno spazio di risposta notevolmente ridotto. Nessun hash difende dalla forza bruta.
tloach

Non ho mai sentito parlare di questa pratica, ma non sono un esperto di sicurezza. Sembra che la crittografia di sali unici aggiungerebbe un ulteriore livello di protezione contro gli attacchi alle tabelle arcobaleno.
Bill the Lizard,

3

... qualcosa come un nome utente o un numero di telefono per salare l'hash. ...

La mia domanda è se il secondo approccio è davvero necessario? Posso capire da una prospettiva puramente teorica che è più sicuro del primo approccio, ma che dire da un punto di vista pratico?

Da un punto di vista pratico, un sale è un dettaglio di implementazione. Se modifichi il modo in cui le informazioni dell'utente vengono raccolte o gestite, e talvolta cambiano sia i nomi utente che i numeri di telefono, per utilizzare i tuoi esempi esatti, potresti aver compromesso la tua sicurezza. Vuoi che un cambiamento così rivolto verso l'esterno abbia problemi di sicurezza molto più profondi?

Interrompere il requisito che ogni account abbia un numero di telefono richiede una revisione completa della sicurezza per assicurarsi di non aver aperto quegli account a una compromissione della sicurezza?


2
Per non parlare del fatto che stai utilizzando un po 'arbitrario di informazioni sull'utente, quando cambiano tali informazioni è necessario che inseriscano di nuovo la password in modo da poterla crittografare di nuovo con il nuovo salt.
Treborbob

3

Un sale nascosto non è più sale. È pepe. Ha il suo uso. È diverso dal sale.

Pepper è una chiave segreta aggiunta alla password + salt che trasforma l'hash in un HMAC (Hash Based Message Authentication Code). Un hacker con accesso all'output hash e al salt può teoricamente indovinare con la forza bruta un input che genererà l'hash (e quindi passare la convalida nella casella di testo della password). Aggiungendo pepe si aumenta lo spazio del problema in modo crittograficamente casuale, rendendo il problema intrattabile senza hardware serio.

Per ulteriori informazioni sul pepe, controlla qui .

Vedi anche hmac .


2

Ecco un semplice esempio che mostra perché è sbagliato avere lo stesso sale per ogni hash

Considera la seguente tabella

UserId  UserName,   Password
     1  Fred       Hash1 =  Sha(Salt1+Password1)    
     2  Ted        Hash2 =  Sha(Salt2+Password2)    

Caso 1 quando salt 1 è uguale a salt2 Se Hash2 viene sostituito con Hash1, l'utente 2 potrebbe accedere con la password dell'utente 1

Caso 2 quando salt 1 non è lo stesso salt2 Se Hash2 viene sostituito con Hash1, l'utente2 non può accedere con la password dell'utente 1.


Non stiamo usando lo stesso hash per ogni account, stiamo usando lo stesso tipo di informazioni per ogni hash. Ad esempio, il sale per un account è il numero di
telefono

So che è passato molto tempo, ma ... non puoi fare affidamento sui sali per proteggerti da questo tipo di attacco. Dobbiamo presumere che un attaccante sappia tutto sul sistema di autenticazione oltre al segreto (cioè la password). Quindi dobbiamo presumere che l'attaccante sappia a) cosa stiamo usando come sale (la maggior parte delle volte questo è memorizzato nello stesso database e tabella in chiaro) eb) come stiamo eseguendo l'hashing con il salt (cioè aggiungendo, hashing-due volte, eccetera). Se l'utente ha la possibilità di cambiare gli hash, allora dobbiamo presumere che possa anche cambiare il sale. I sali non aiuteranno qui.
Dave Satch

1

Esistono due tecniche, con obiettivi diversi:

  • Il "salt" viene utilizzato per fare in modo che due password altrimenti uguali vengano crittografate in modo diverso. In questo modo, un intruso non può utilizzare in modo efficiente un attacco del dizionario contro un intero elenco di password crittografate.

  • Il "segreto" (condiviso) viene aggiunto prima dell'hashing di un messaggio, in modo che un intruso non possa creare i propri messaggi e farli accettare.


0

Tendo a nascondere il sale. Uso 10 bit di sale anteponendo un numero casuale da 1 a 1024 all'inizio della password prima di hashing. Confrontando la password inserita dall'utente con l'hash, faccio un ciclo da 1 a 1024 e provo ogni possibile valore di salt fino a trovare la corrispondenza. Questo richiede meno di 1/10 di secondo. Ho avuto l'idea di farlo in questo modo da PHP password_hash e password_verify . Nel mio esempio, il "costo" è 10 per 10 bit di sale. O da quello che ha detto un altro utente, il "sale" nascosto è chiamato "pepe". Il sale non è crittografato nel database. È bruto costretto a uscire. Renderebbe necessario il tavolo arcobaleno per invertire l'hash 1000 volte più grande. Uso sha256 perché è veloce, ma comunque considerato sicuro.


Quindi, se la mia password è "345678" e il salt casuale che anteponi sembra essere, ad esempio, "12". Se qualcuno inserisce "45678" come password. Questo sembra sbagliato in molti modi.
Yurippenet

-1

In realtà, dipende dal tipo di attacco che stai tentando di proteggere i tuoi dati.

Lo scopo di un salt univoco per ogni password è impedire un attacco del dizionario contro l'intero database delle password.

Crittografare il sale univoco per ogni password renderebbe più difficile decifrare una singola password, sì, ma devi valutare se c'è davvero un grande vantaggio. Se l'aggressore, con la forza bruta, scopre che questa stringa:

Marianne2ae85fb5d

hash su un hash memorizzato nel DB, è davvero così difficile capire quale parte è il passaggio e quale parte è il sale?


2
Se un bruto costringe una password così impossibile da indovinare, direi che sei comunque imbrogliato, perché a quanto pare hanno una tecnologia a cui nessuno ha ancora pensato.
Instance Hunter
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.