Cosa rende "sicuro" un algoritmo di hashing?


19

Dopo aver letto questa interessante domanda, mi è sembrato di avere una buona idea di quale algoritmo di hashing non sicuro avrei usato se ne avessi avuto bisogno, ma non ho idea del perché potrei usare un algoritmo sicuro.

Quindi qual è la distinzione? L'output non è solo un numero casuale che rappresenta la cosa hash? Cosa rende sicuri alcuni algoritmi di hashing?


8
Questa domanda è più adatta per il sito IT Security SE.
Bernard,

@Bernard Se è così, allora sto bene, ma la mia domanda non era davvero su come o quando usare un hash sicuro, ma cosa distingue un algoritmo di hashing sicuro da uno non sicuro. Mi sembra più una domanda di programmazione, ma non sfoglio IT Security SE quindi forse funziona anche lì.
CodexArcanum,

2
Una domanda molto simile è già stata posta sulla sicurezza IT
ChrisF

Risposte:


34

Esistono tre proprietà che si desidera da ogni funzione hash crittografica H:

  • resistenza preimage : dato h, dovrebbe essere difficile trovare alcun valore xcon h = H(x).

  • seconda resistenza preimage : Dato x1, dovrebbe essere difficile trovare x2 != x1con H(x1) = H(x2).

  • resistenza alla collisione : dovrebbe essere difficile trovare due valori x1 != x2con H(x1) = H(x2).

Con le funzioni hash utilizzate nei linguaggi di programmazione comuni per le tabelle hash (di stringhe), di solito nessuna di queste viene fornita, prevedono solo:

  • resistenza alla collisione debole : per valori selezionati casualmente (o "tipicamente") del dominio, la possibilità di collisione è ridotta. Questo non dice nulla di un utente malintenzionato che tenta intenzionalmente di creare collisioni o di cercare pre-immagini.

Le tre proprietà sopra sono (tra) gli obiettivi di progettazione per ogni funzione hash crittografica. Per alcune funzioni (come MD4, SHA-0, MD5) è noto che ciò è fallito (almeno in parte). Si presume che l'attuale generazione (SHA-2) sia sicura e quella successiva ("Secure Hash Algorithm 3") è attualmente in fase di standardizzazione , dopo una competizione .

Per alcuni usi (come l'hash delle password e la derivazione delle chiavi dalle password), il dominio dei valori effettivamente utilizzati xè così piccolo che forzare brutalmente questo spazio diventa fattibile con le normali funzioni di hash sicure (veloci), e questo è quando vogliamo anche:

  • esecuzione lenta : dato x, ci vuole una quantità minima (preferibilmente configurabile) di risorse per calcolare il valore H(x).

Ma per la maggior parte degli altri usi, questo non è voluto, si vuole invece:

  • esecuzione veloce : dato x, il calcolo del valore di H(x)è il più veloce possibile (mentre è ancora sicuro).

Ci sono alcune costruzioni (come PBKDF2 e scrypt) per creare una funzione hash lenta da una veloce ripetendola spesso.

Per ulteriori dettagli, dai un'occhiata al tag hash sul nostro sito gemello Cryptography Stack Exchange.


3

Sicuro significa che qualcuno che vuole indurti in errore usando una collisione (cioè il fatto che due fonti siano sottoposte allo stesso valore) avrà difficoltà.

Alcune caratteristiche:

  • conoscere l'hash, costruire un file che ha hash a quel valore è difficile (variante, viene fornita una parte del nuovo file e l'hash desiderato)

  • costruire due file diversi che ha lo stesso valore di hash è difficile (viene fornita una variante, parte dei file)


3

La differenza principale è piuttosto semplice: un hash normale ha lo scopo di ridurre al minimo il numero di collisioni accidentali, nella misura in cui può senza rallentare molto nel processo.

Un hash sicuro che intendeva prevenire le collisioni, anche quando qualcuno fa del suo meglio per causarne una. In genere non si desidera scambiare alcuna possibilità di collisione per un funzionamento più rapido. In effetti, rendere l'operazione intenzionalmente lenta comporta alcuni vantaggi in termini di sicurezza, anche se non è più difficile trovare collisioni.

Per un esempio di quest'ultimo: se il calcolo di un hash richiede 50 ms, non avrà un impatto materiale sull'accesso di un utente normale (ovvero, la maggior parte degli utenti non noterà una differenza di 50 ms quando effettuano l'accesso). Allo stesso tempo, se un attaccante vuole fare un attacco con dizionario, essere in grado di produrre solo 20 hash al secondo è un grave handicap. In altre parole, per qualche motivo, per un hash sicuro, è meglio rallentare.


3
Nel dominio delle funzioni hash crittografiche, ci sono due importanti sottogruppi: quelli veloci (usati per l'autenticazione dei messaggi, la firma e simili) e quelli lenti - usati per la derivazione delle chiavi e l'hash delle password. Non mescolarli, ci sono applicazioni per entrambi.
Paŭlo Ebermann,

In realtà, ci sono anche funzioni hash progettate per massimizzare le collisioni: Soundex ne è un esempio. Ovviamente, questo lo rende una funzione hash sicura molto scadente.
Jörg W Mittag,

@ JörgWMittag: non solo schifoso come hash sicuro, ma sarebbe anche piuttosto scarso per l'uso con una tabella hash. Poi di nuovo, anche se certamente in qualche modo simile all'hash, esiterei a chiamare Soundex una funzione di hash, semplicemente perché il suo intento e il suo utilizzo sono così completamente diversi dalle normali funzioni di hash.
Jerry Coffin,

@JerryCoffin: immagino che dipenda dalla definizione. Ad esempio, la pagina Wikipedia in inglese dice semplicemente che una funzione hash è qualsiasi algoritmo o subroutine che mappa un insieme più grande (potenzialmente infinito) di valori arbitrari in un insieme più piccolo e finito di valori (tipicamente scalari). Considerando che la pagina tedesca di Wikipedia afferma che l '"hashing" (tedesco: "zerhacken") è parte integrante, vale a dire che la prevenzione delle collisioni e la distribuzione dei valori mappati è la chiave. Soundex soddisfa molto la prima definizione ma non la seconda.
Jörg W Mittag,

3

Leggi questo http://www.codinghorror.com/blog/2012/04/speed-hashing.html che spiegherà tutto molto meglio di quanto io possa mai spiegarlo. Ecco le due intestazioni più importanti nell'articolo che affrontano direttamente la tua domanda:

  • Gli hash sicuri sono progettati per essere a prova di manomissione
    • cambia radicalmente il suo output con minuscole modifiche a singolo bit ai dati di input
  • Gli hash sicuri sono progettati per essere lenti

La sua sezione TL; DR alla fine:

Se sei un utente:

Assicurati che tutte le tue password siano di 12 caratteri o più, idealmente molto di più. Consiglio di adottare frasi d'accesso, che non sono solo molto più facili da ricordare delle password (se non di tipo), ma anche ridicolmente sicure contro la forza bruta puramente a causa della loro lunghezza.

Se sei uno sviluppatore:

Usa bcrypt o PBKDF2 esclusivamente per eseguire l'hashing di tutto ciò che ti serve per essere sicuro. Questi nuovi hash sono stati appositamente progettati per essere difficili da implementare su GPU. Non utilizzare altre forme di hash. Quasi tutti gli altri schemi di hashing popolari sono vulnerabili alla forzatura bruta da matrici di GPU di materie prime, che diventano solo più veloci, più parallele e più facili da programmare per ogni anno.


4
Jeff ha sbagliato qui sul secondo punto ... mentre per alcuni usi (come hashing della password e derivazione della chiave da una password) vuoi essere lento, per altri usi (come l'autenticazione dei messaggi, firme, ecc.) Veloce (sicuro) le funzioni hash sono buone.
Paŭlo Ebermann,

Hai ragione Paŭlo. Le prestazioni dell'hash dipendono dall'applicazione dell'hash. Tuttavia, gli hash lenti sono sempre più sicuri di quelli veloci. Il motivo per cui dovresti usare un hash veloce è se stai sacrificando la sicurezza per le prestazioni.
Nate,

2
@Nate “Più sicuro” è sempre ambiguo, ma anche sotto l'applicazione più benefica, “gli hash lenti sono sempre più sicuri di quelli veloci” è sicuramente sbagliato. Esistono molte applicazioni in cui la velocità di un hash è irrilevante.
Gilles 'SO- smetti di essere malvagio' il

@Gilles puoi fare un esempio? In realtà sembra vero per me, ma più dettagli sarebbero utili.
Nate,

2
@Nate L'applicazione più ovvia degli hash sta verificando l'integrità di un dato: trasmettere l'hash su un canale sicuro ma possibilmente a larghezza di banda ridotta, trasmettere il payload possibilmente grande su un canale non sicuro, quindi verificare che il payload ricevuto abbia il previsto hash. Gli hash sono anche importanti nei metodi di firma (in cui non solo verifichi l'integrità, ma anche chi ti ha inviato i dati). Hashing password è piuttosto l'eccezione.
Gilles 'SO- smetti di essere malvagio' il

2

Un hash "sicuro" è un hash che si ritiene sia difficile "spoofare" in modo formulabile e riproducibile senza una conoscenza preliminare del messaggio utilizzato per creare l'hash. Poiché tali informazioni sono generalmente segrete, quindi la necessità di un hash, questa è una buona proprietà di una funzione di hashing destinata all'uso nell'autenticazione.

Un hash è generalmente considerato "sicuro" se, dato un messaggio M, una funzione hash hash () e un valore hash H prodotto da hash (M) con una lunghezza in bit L, nessuna delle seguenti operazioni può essere eseguita in meno di O (2 L ) tempo:

  • Dato hash () e H, produce M. (resistenza preimage)
  • Dato hash () e M, produce un M 2 diverso tale che hash (M 2 ) == H. (resistenza alla collisione debole)
  • Dato hash (), produce qualsiasi M 1 e M 2 tale che hash (M 1 ) == hash (M 2 ). (forte resistenza alle collisioni)

Inoltre, un hash "sicuro" deve avere una lunghezza hash L tale che 2 Lnon è un numero fattibile di passaggi per un computer per eseguire l'hardware corrente dato. Un hash intero a 32 bit può avere solo 2,1 miliardi di valori; mentre un attacco preimage (trovare un messaggio che produce un hash H specifico) richiederebbe un po 'di tempo, non è fattibile per molti computer, in particolare quelli nelle mani di agenzie governative noleggiate con la violazione del codice. Inoltre, un algoritmo che crea e archivia messaggi casuali e i loro hash avrebbero, secondo le probabilità, una possibilità del 50% di trovare un hash duplicato con ogni nuovo messaggio dopo aver provato solo 77.000 messaggi e avere una probabilità del 75% di colpire un duplicato dopo solo 110.000. Anche gli hash a 64 bit hanno ancora il 50% di probabilità di scontrarsi dopo aver provato solo circa 5 miliardi di valori. Tale è il potere dell'attacco di compleanno a piccoli hash. Al contrario,numeri decilioni (1,5 * 10 34 ).

La maggior parte degli attacchi dimostrati agli hash crittografici sono stati attacchi di collisione e hanno dimostrato la capacità di generare messaggi di collisione in meno di 2 L di tempo (la maggior parte è stata ancora in tempo esponenziale, ma ridurre l'esponente della metà è una riduzione significativa della complessità in quanto rende un hash a 256 bit facile da risolvere come un 128 bit, un 128 bit facile da risolvere come un 64 bit, ecc.).

Oltre alle piccole dimensioni dell'hash, altri fattori che possono rendere un hash dimostrabilmente insicuro sono:

Basso lavoro: un hash progettato per essere utilizzato da una hashtable o per altri scopi di tipo "checksum" è generalmente progettato per essere computazionalmente economico. Ciò rende molto più facile un attacco a forza bruta.

"Sticky State" - La funzione di hashing è soggetta a schemi di input in cui il valore di hash corrente di tutti gli input finora non cambia quando viene dato un particolare byte aggiuntivo di input. Avere "stato appiccicoso" facilita la ricerca di collisioni, perché una volta identificato un messaggio che produce un hash "stato appiccicoso" è banale generare altri messaggi che hanno lo stesso hash aggiungendo byte di input che mantengono l'hash nel suo "stato appiccicoso" ".

Diffusione: ogni byte di input del messaggio deve essere distribuito tra i byte del valore hash in un modo altrettanto complesso. Alcune funzioni hash creano modifiche prevedibili a determinati bit nell'hash. Ciò rende di nuovo banale la creazione di collisioni; dato un messaggio che produce un hash, le collisioni possono essere facilmente create introducendo nuovi valori nel messaggio che influenzano solo i bit che cambiano in modo prevedibile.


0

Utilizzare l'algoritmo giusto per l'attività in corso.

I CRC vengono utilizzati per il rilevamento / correzione degli errori.

I digest di messaggi crittografici come SHA2 sono usati come blocchi predefiniti per costrutti crittografici (firme digitali, MAC, derivazione chiave / funzioni di hashing delle password) e protocolli di sicurezza.

Nelle tabelle hash / dizionari / mappe usa SipHash .

Gli algoritmi di hashing non sicuri non devono essere utilizzati nelle tabelle hash , come dimostrato dalle seguenti voci CVE: CVE-2003-0364, CVE-2011-4461, CVE-2011-4838, CVE-2011-4885, CVE-2011- 4462, CVE-2011-4815, CVE-2012-0840, CVE-2012-5371 , CVE-2012-5374, CVE-2012-5375

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.