it-swarm.it

Perché le funzioni hash sono a senso unico? Se conosco l'algoritmo, perché non riesco a calcolare l'input da esso?

Perché un hash password non può essere decodificato?

Ne ho esaminato secoli fa e ne ho letto molto, ma non riesco a trovare la spiegazione del perché non possa essere fatto. Un esempio renderà più semplice la comprensione della mia domanda e per semplificare le cose, la baseremo su un algoritmo di hashing che non usa un salt ( LanMan ).

Di 'che la mia password è "Password". LanMan eseguirà questo hash e lo memorizzerà nel database. I programmi di cracking possono forzare la forza di questi tentativi di hashing della password forniti. Quindi confronta l'hash generato con l'hash nel database. Se c'è una corrispondenza, trova la password.

Perché, se il cracker di password conosce l'algoritmo per trasformare una password di testo semplice in un hash, non può semplicemente invertire il processo per calcolare la password dall'hash?

Questa domanda era Domanda sulla sicurezza IT della settimana.
Leggi il 24 febbraio 2012 post di blog per maggiori dettagli o invia il tuo Domanda della settimana.

231
Mucker

Vorrei inventare un semplice "algoritmo di hashing delle password" per mostrarti come funziona. A differenza degli altri esempi in questo thread, questo è effettivamente praticabile, se puoi vivere con alcune strane restrizioni sulla password. La tua password è composta da due numeri primi grandi, x e y. Ad esempio :

x = 48112959837082048697
y = 54673257461630679457

Puoi facilmente scrivere un programma per calcolare xy in O ( [~ # ~] n [~ # ~ ] ^ 2) ora, dove [~ # ~] n [~ # ~] è il numero di cifre in x e y. (Fondamentalmente ciò significa che ci vogliono quattro volte purché i numeri siano lunghi il doppio. Esistono algoritmi più veloci, ma questo è irrilevante. Memorizzare xy nel database delle password.

x*y = 2630492240413883318777134293253671517529

Un bambino in quinta elementare, con abbastanza carta da grattare, poteva capire quella risposta. Ma come si inverte? Ci sono molti algoritmi che le persone hanno escogitato per il factoring di grandi numeri, ma anche i migliori algoritmi sono lenti rispetto a quanto velocemente puoi moltiplicare x per y. E nessuno di quegli algoritmi può essere eseguito da un quinto selezionatore, a meno che i numeri non siano molto piccoli (ad es. x = 3, y = 5).

Questa è la proprietà chiave: il calcolo è molto più semplice andare avanti che indietro. Per molti problemi, è necessario inventare un algoritmo completamente nuovo per invertire un calcolo.

Questo non ha nulla a che fare con le funzioni iniettive o biiettive. Quando stai violando una password, spesso non importa se ottieni la stessa password o se ottieni una password diversa con lo stesso hash. La funzione hash è progettata per cui è difficile invertirla e ottenere qualsiasi risposta, anche una password diversa con lo stesso hash. In crypto-speak: una funzione hash vulnerabile a un attacco preimage è assolutamente priva di valore. (L'algoritmo di hashing della password sopra è iniettivo se hai una regola che x < y. )

Cosa fanno gli esperti di crittografia? A volte, cercano di capire nuovi algoritmi per invertire una funzione hash (pre-immagine). Fanno esattamente quello che dici: analizza l'algoritmo e prova a invertirlo. Alcuni algoritmi sono stati invertiti prima, altri no.

Esercizio per il lettore: Supponiamo che il database delle password contenga la seguente voce:

3521851118865011044136429217528930691441965435121409905222808922963363310303627

Qual è la password? (Questo in realtà non è troppo difficile per un computer.)

Nota a piè di pagina: A causa del piccolo numero di password che le persone scelgono in pratica, un buon hash delle password non è semplicemente difficile da calcolare all'indietro, ma richiede tempo anche per il calcolo in avanti, per rallentare gli attacchi del dizionario. Come ulteriore livello di protezione, il sale randomizzato impedisce l'uso di tabelle di attacco pre-calcolate (come "tabelle arcobaleno").

Nota 2: Come sappiamo che è difficile invertire una funzione hash? Sfortunatamente no. Semplicemente non conosciamo alcun modo semplice per invertire le funzioni di hash. Fare una funzione di hash che è dimostrabilmente difficile da invertire è il santo graal del design della funzione di hash, e non è stato ancora raggiunto (forse non accadrà mai).

235
Dietrich Epp

Questa è una buona domanda.

Dobbiamo prima dare una precisione: molte funzioni a senso unico, in particolare la funzione hash come comunemente usata nella crittografia, accettano input da uno spazio che è molto più grande dello spazio dei valori di output. Ad esempio, SHA-256 è definito per gli ingressi che sono stringhe fino a 18446744073709551615 bit; ci sono 218446744073709551616-1 input possibili, ma poiché l'output è sempre una sequenza di 256 bit, ci sono solo 2256 uscite possibili per SHA-256. Necessariamente, alcuni input distinti producono lo stesso output. Pertanto, per un determinato output di SHA-256, non è possibile ripristinare in modo inequivocabile l'input che è stato utilizzato, ma, possibilmente, potrebbe essere possibile calcolare un input che produce il valore di output dato. Preimage resistenza è a questo proposito: la difficoltà di trovare un input corrispondente per un output (indipendentemente da come quell'output è stato ottenuto in primo luogo).

Quindi parliamo di una funzione che tutti possono calcolare su qualsiasi input (utilizzando un programma noto pubblicamente, senza alcun valore segreto coinvolto - non stiamo parlando di crittografia).


Cosa dicono gli accademici

Non è chiaro se le funzioni a senso unico possano effettivamente esistere. In questo momento, abbiamo molte funzioni che nessuno sa invertire; ma ciò non significa che siano impossibili invertire, in senso matematico. Si noti, tuttavia, che non è dimostrato che le funzioni a senso unico non possano esistere, quindi la speranza rimane. Alcune persone sospettano che l'esistenza o meno di funzioni a senso unico potrebbe essere una di queste fastidiose asserzioni matematiche che non possono essere né provate né smentite ( il teorema di Gödel dimostra che tali cose devono esistere). Ma non c'è nemmeno prova di ciò.

Pertanto, non vi è alcuna prova che una determinata funzione di hash sia davvero resistente alle preimmagini.

Ci sono alcune funzioni che possono essere collegate a noti problemi difficili. Ad esempio, se n è il prodotto di due numeri primi grandi, la funzione x x2 mod n è difficile da invertire: essere in grado di calcolare le radici quadrate modulo un intero non primo n ( su base generale) equivale a essere in grado di fattore n , e questo problema è noto per essere difficile. Non provato di essere difficile, intendiamoci; solo che i matematici hanno cercato di fattorizzare in modo efficiente i grandi numeri interi per (almeno) negli ultimi 2500 anni, e sebbene siano stati compiuti alcuni progressi, nessuna di queste persone intelligenti ha trovato un algoritmo davvero killer per quello. Il record mondiale per la fattorizzazione di un "modulo RSA" (un prodotto di due primi primi scelti a caso di lunghezze simili) è n numero intero di 768 bit .

Sono state proposte alcune funzioni di hash basate su tali "problemi difficili"; vedere ad esempio MASH-1 e MASH-2 (sul problema RSA ) e ECOH ( con curve ellittiche). Esistono solo alcune di queste funzioni, perché:

  • Trasformare un "problema difficile" in una funzione hash sicura non è facile; ci sono molte questioni difficili. Ad esempio, durante l'estrazione di radici quadrate modulo un non primo n è di solito duro, ci sono valori per i quali l'estrazione di radice quadrata è facile.

  • Le prestazioni di tali funzioni hash tendono ad essere, diciamo, non ottimali. Come essere 100 volte più lento di un SHA-1 più comunemente usato.

Il modo più "standard" di costruire una funzione hash è mettere insieme i crittografi e farli rosicchiare in alcuni progetti proposti; le funzioni che sopravvivono ai tentativi crittoanalitici per alcuni anni vengono quindi considerate "probabilmente robuste". SHA-3 competition è un tale sforzo; il vincitore dovrebbe essere annunciato entro la fine dell'anno. Sui 51 candidati (quelli che hanno superato la fase amministrativa), 14 sono stati mantenuti per il "round 2" e questi 14 sono stati osservati relativamente da vicino da molti crittografi, e nessuno di loro ha trovato qualcosa di veramente degno di dire sulle funzioni. L'elenco è stato ridotto a 5 e verrà ulteriormente ridotto a 1 "presto", ma non per motivi di sicurezza (la maggior parte dei dati effettivi riguardava le prestazioni, non la resistenza).


Cosa rende difficile invertire MD5

Poiché non sappiamo come dimostrare che una funzione è difficile da invertire, la cosa migliore che possiamo fare è provarla su una funzione specifica, in modo da ottenere un " intuizione "di come la funzione raggiunge la sua apparente resistenza.

Scelgo MD5 , che è ben noto. Sì, MD5 è "rotto" , ma è per le collisioni, non per le preimmagini. C'è è un noto attacco preimage che è, almeno teoricamente, più veloce del modo generico (il "modo generico" è "fortuna", cioè provare input fino a quando non viene trovata una corrispondenza, per un costo medio di 2128 valutazioni poiché MD5 ha un output a 128 bit; attacco Sasaki-Aoki ha un costo 2123.4, che è inferiore, ma comunque troppo alto per essere effettivamente provato, quindi il risultato è ancora teorico). Ma MD5 è relativamente semplice e ha resistito agli attacchi per un po 'di tempo, quindi è un esempio interessante.

MD5 consiste in una serie di valutazioni di una "funzione di compressione" su blocchi di dati. Il messaggio di input viene prima riempito, in modo che la sua lunghezza diventi un multiplo di 512 bit. Viene quindi suddiviso in blocchi da 512 bit. Uno stato di esecuzione a 128 bit (contenuto in quattro variabili a 32 bit chiamate [~ # ~] a [~ # ~] , [~ # ~ ] b [~ # ~] , [~ # ~] c [~ # ~] e [~ # ~] d [~ # ~] ) viene inizializzato su un valore convenzionale, quindi elaborato con la funzione di compressione . La funzione di compressione accetta lo stato corrente e un blocco messaggi a 512 bit e li mescola in un nuovo valore per lo stato corrente. Quando tutti i blocchi di messaggi sono stati così elaborati, il valore finale dello stato in esecuzione è l'output hash.

Quindi concentriamoci sulla funzione di compressione. Funziona così:

  • Ingressi: lo stato corrente ( ABC D) e un blocco messaggi [~ # ~] m [~ # ~] . Il blocco messaggi è 512 bit; lo dividiamo in 16 parole a 32 bit M, M1, M2, ... M15.
  • Output: il nuovo valore dello stato corrente.
  • In lavorazione:

    1. Salva lo stato corrente in alcune variabili: A → A ', B → B' , C → C ' e D → D'
    2. Fai 64 round che assomigliano a questo:
      • Calcola T = B + ((A + fio(B, C, D) + Mk + Xio) <<< sio) . Questo è il seguente: calcoliamo una determinata funzione fio (una semplice funzione bit a bit, che dipende dal numero di round i ) over [~ # ~] b [~ # ~] , [~ # ~] c [~ # ~] e [~ # ~] d [~ # ~] . Aggiungete a ciò il valore di [~ # ~] a [~ # ~] , un messaggio Word Mk e una costante Xio (le aggiunte sono fatte modulo 232). Ruota il risultato a sinistra di alcuni bit (la quantità di spostamento dipende anche dal giro). Infine, aggiungi [~ # ~] b [~ # ~] : il risultato è [~ # ~] t [~ # ~] .
      • Ruota le parole di stato: D → A , C → D , B → C , T → B .
    3. Aggiungi i valori di stato salvati alle variabili di stato correnti: A + A '→ A , B + B' → B , C + C '→ C , D + D' → D .

Il punto importante è che ci sono 64 round, ma solo 16 parole di messaggio. Ciò significa che ogni messaggio Word entra nell'elaborazione quattro volte . Lo scrivo in grassetto perché è il punto centrale; la resistenza alle preimmagini deriva da quella caratteristica. Quale messaggio Word viene utilizzato in ogni round è descritto nelle specifiche MD5 (RFC 1321); la specifica descrive anche le funzioni fio, la rotazione conta sio e le costanti a 32 bit Xio.

Supponiamo ora che tu stia tentando di "invertire" MD5; si parte dall'output e si aumenta lentamente la funzione di compressione. Innanzitutto, devi decidere l'output del round 64. In effetti, l'output della funzione di compressione è la somma dell'output del round 64 e lo stato salvato (il A 'B' C 'D' valori). Non hai nessuno dei due, quindi devi scegliere. La tua speranza è che sarai in grado di trovare valori per le parole del messaggio che ti consentiranno di ottenere per l'immissione del round 1 alcuni valori coerenti con la tua decisione arbitraria su A ' e i suoi fratelli.

Vediamo come appaiono le cose quando si cammina indietro la funzione di compressione. Hai l'output di un round (le variabili [~ # ~] a [~ # ~] , [~ # ~] b [~ # ~] , [~ # ~] c [~ # ~] e [~ # ~] d [~ # ~] dopo il round) e vuoi ricalcolare l'ingresso di quel round. Conosci già i valori precedenti di [~ # ~] b [~ # ~] , [~ # ~] c [~ # ~] e [~ # ~] d [~ # ~] , ma per [~ # ~] a [~ # ~] e Mk hai molta scelta: ogni valore a 32 bit è possibile per [~ # ~] a [~ # ~] e ognuno ha un corrispondente Mk. All'inizio, ne sei contento; chi respingerebbe tale libertà? Basta scegliere una M casuale k e questo produce il corrispondente [~ # ~] a [~ # ~] con solo poche operazioni (provalo!).

Ma dopo aver invertito in questo modo 16 round (i round da 49 a 64, poiché stai lavorando all'indietro), la libertà scompare. Hai "scelto" i valori di tutte le parole del messaggio. Quando si tenta di invertire il round 48, si desidera ricalcolare il valore di [~ # ~] a [~ # ~] appena prima di quel round; secondo la specifica MD5, messaggio Word M2 è usato al round 48 e hai già scelto il valore di M2 (quando si inverte il giro 63). Quindi c'è solo una scelta per [~ # ~] a [~ # ~] . E allora, diresti. Una scelta è sufficiente per continuare la camminata all'indietro. Quindi continui.

Ora sei all'inizio della funzione di compressione. Ricorda che, inizialmente, hai fatto una scelta arbitraria dei valori di A 'B' C 'D' : questo ti ha permesso di calcolare l'output del round 64, e iniziare indietro camminare. Ora hai ottenuto l'input del round 1, che dovrebbe essere identico a A 'B' C 'D' ... e non corrisponde. È abbastanza normale: hai scelto A 'B' C 'D' arbitrariamente, e hai anche scelto le parole del messaggio Mk arbitrariamente, quindi ci si può aspettare che non funzionerà per la maggior parte del tempo. Quindi si tenta di riparare il calcolo, modificando retrospettivamente la scelta iniziale di A 'B' C 'D' , oppure una o più delle scelte casuali per Mk. Ma ogni modifica su qualsiasi Mk implica modifiche altrove, poiché ciascuna Mk viene utilizzato quattro volte. Quindi hai bisogno di altre modifiche per annullare le altre, e così via ...

A quel punto inizi a capire il problema di invertire MD5: ogni volta che tocchi un singolo bit, innesca moltissime modifiche in tutto l'algoritmo, che devi annullare toccando altri bit e ci sono troppe interazioni . Fondamentalmente, si destreggia con 2128 palle allo stesso tempo, ed è troppo per tenere traccia di tutte.

Se ogni blocco di messaggi era lungo 2048 bit, diviso in 64 parole e ogni parola di messaggio veniva utilizzata una sola volta in MD5, è possibile invertire facilmente. Fai come sopra: selezione arbitraria di A 'B' C 'D' , selezione arbitraria di parole messaggio per i round da 64 a 5; e per i primi quattro round, prendi semplicemente in considerazione il valore che desideri ottenere per l'input del round (il valore che corrisponde alla tua scelta arbitraria di A ', B ', C' o D ') ed elabora il corrispondente messaggio Word. Facile come una torta. Ma MD5 non elabora i dati per blocchi a 2048 bit, ma per blocchi a 512 bit e ogni messaggio Word viene utilizzato quattro volte.


Alcuni colpi di scena aggiuntivi

La struttura della funzione di compressione di MD5 è in realtà una generalizzazione di un Feistel cipher . In un codice Feistel, i dati sono divisi in due metà e, per ogni round, ne alteriamo la metà aggiungendola/xoring a un valore intermedio che viene calcolato dall'altra metà e dalla chiave; e poi scambiamo le due metà. Estendi questo schema a una suddivisione in quattro parti e otterrai la stessa struttura dei round MD5 - con una rotazione di 90º: MD5 sembra la crittografia dello stato corrente usando il blocco messaggi come tasto (e c'è l'aggiunta aggiuntiva dell'output del round 64 con lo stato salvato, che separa MD5 da un codice ruotato).

Quindi forse possiamo costruire funzioni di hash da cifrature a blocchi? In effetti possiamo: questo è Whirlpool . Una funzione hash costruita su un codice a blocchi ruotato (il blocco messaggi è la chiave); il codice a blocchi di Whirlpool è "W", un derivato di Rijndael, meglio noto come AES . Ma W ha blocchi più grandi (512 bit anziché 128 bit) e un programma di chiavi riforgiato.

Quando si effettua una funzione hash da un codice a blocchi ruotato, gli attacchi preimage sulla funzione hash sono in qualche modo equivalenti agli attacchi di ricostruzione chiave sul codice a blocchi; quindi c'è qualche speranza che se il codice a blocchi è sicuro, allora lo è anche la funzione hash. Anche in questo caso, ci sono dettagli snarky. Inoltre, per tale struttura, collisioni sulla funzione hash sono come attacchi con chiave correlata sulla cifra di blocco; gli attacchi con chiavi correlate sono generalmente considerati non fatali e spesso ignorati (ad esempio, non facevano parte dei criteri di valutazione per la competizione AES, e Rijndael è considerato un po 'traballante in questo senso, motivo per cui W ha una chiave nuova di zecca programma).

Alcuni progetti più recenti sono costruiti su un codice a blocchi che non è non ruotato, in modo che la sicurezza della funzione hash possa essere derivata più direttamente dalla sicurezza del codice a blocchi; vedere ad esempio il candidato SHA-3 Skein , definito su un codice a blocchi chiamato Threefish.

Al contrario, si potrebbe provare a creare un codice a blocchi da una funzione hash. Vedi ad esempio SHACAL , che è SHA-1 "impostato in posizione verticale". E, a titolo indicativo, SHACAL presenta alcune debolezze chiave correlate che sono abbastanza simili alle debolezze note di SHA-1 per quanto riguarda le collisioni (non è stata calcolata alcuna collisione effettiva, ma abbiamo un metodo che dovrebbe essere quasi un milione di volte più veloce del algoritmo di ricerca delle collisioni generico).

Pertanto, contrariamente a quanto ho detto nell'introduzione di questo post, abbiamo sempre parlato di crittografia . C'è ancora molto da scoprire e studiare sui collegamenti tra le funzioni hash e la crittografia simmetrica.


TL; DR: non c'è TL; DR per questo messaggio. Leggi tutto o generalo.

128
Thomas Pornin

Il primo passo verso la risposta qui è vedere esempi, come quello di Nice di @Dietrich, di funzioni che sono molto più difficili da eseguire in una direzione rispetto all'inverso, e hanno resistito a molti tentativi di trovare una svolta di velocità. Ma il problema è complesso, quindi cercherò di risolverlo un po 'di più.

Molte persone sembrano cadere nella trappola (eh) di pensare che le funzioni di hash siano in realtà in qualche modo magiche - che siano veramente "funzioni a senso unico" che matematicamente non possono essere eseguite all'indietro affatto, solo perché si chiamano hash. Questo non è un modo salutare per pensarci in un forum sulla sicurezza. È spesso sbagliato nella pratica. Ed è sempre sbagliato in teoria, data la definizione matematica di base di una funzione come mappatura da un dominio a un'immagine .

Tutti gli hash possono essere invertiti, in linea di principio. Può essere disordinato e brutale (come nella forza bruta), potrebbe richiedere un tempo impraticabilmente lungo con l'hardware di oggi, e potrebbe anche resistere a lungo raggio, ma matematicamente è semplicemente una questione di tempo. Come notato da @mucker, tutte le informazioni sono lì per trovare la password originale (o, almeno, una password che funziona). Se lo dimentichiamo, dimentichiamo il pericolo di un'euristica intelligente per la raccolta delle password probabili, che rendono le notizie regolarmente. L'hashing è un problema di ingegneria e la sfida principale è quella dell'efficienza: come rendere costoso trovare la password data dall'hash. Uno dei risultati principali di questo tipo di pensiero è l'importanza di rendere gli hash delle password lenti

E la scienza e la matematica dell'hashish stanno lentamente migliorando. Non ci sono prove che gli hash siano davvero difficili. La risposta di @ Dietrich è un bel modo di illustrare come le funzioni di hash ideali potrebbero essere possibili. Ma basta guardare i veri esperti che descrivono come non abbiamo prove per nessuno dei migliori algoritmi crittografici: Qual è il modello matematico dietro le affermazioni sulla sicurezza di cifre simmetriche e algoritmi digest?

Il fatto che LanMan sia stato citato nella domanda è ancora una prova in più che dobbiamo evitare di idealizzare gli hash. LanMan è tutt'altro che una funzione hash ideale, facilmente sconfitta da una combinazione di un po 'di analisi e un po' di forza bruta. Per un altro esempio popolare di una orribile funzione hash vedi MySQL OLD_PASSWORD cryptanalysis? .

Quindi rimettiti fuori dalla trappola - cadere in essa non deve essere un viaggio di sola andata. Riconosci che gli hash sono reversibili e mantieni attiva quella fidata mentalità di sicurezza mentre cerchi il modo migliore per invertirli. Questo è spesso il modo migliore per trovare quelli che sono davvero difficili da invertire. Non sto cercando di lanciare aspersioni sulle migliori pratiche là fuori, come bcrypt o PBKDF2 o scrypt. Ma l'evidenza è chiara che anche i bravi programmatori sbagliano troppo spesso questa roba. quindi fai attenzione a come li usi e non cercare di inventare i tuoi.

17
nealmcb

Perché è così che funzionano le funzioni crittografiche di hash, sono funzioni matematiche unidirezionali (da semplici a hash). Gli algoritmi sono realizzati e testati appositamente per evitarlo e anche per evitare collisioni (2 testi in chiaro diversi generano lo stesso hash).

Puoi leggere di più su wikipedia , ma il punto principale dell'articolo è:

La funzione hash crittografica ideale ha quattro proprietà principali o significative:

  • è facile (ma non necessariamente rapido) calcolare il valore di hash per un dato messaggio
  • è impossibile generare un messaggio con un determinato hash
  • è impossibile modificare un messaggio senza cambiare l'hash
  • è impossibile trovare due messaggi diversi con lo stesso hash

La maggior parte degli attacchi alle funzioni hash si basa sulla ricerca di collisioni (quindi 2 diversi testi in chiaro corrisponderanno allo stesso hash) o sulla pre-generazione di milioni di hash e sul loro confronto fino a trovare la pianura che lo ha generato.

Breve storia: se un algoritmo di hash è retroingegnerizzabile o può essere attaccato in quel modo, non è un buon algoritmo di hash.

Per le password, indagando su BCrypt, questo post contiene molte informazioni.

12
coredump

Immagina una funzione hash che utilizza un singolo bit per l'hash. Quindi il tuo hash può essere 0 o 1.

E supponiamo che la funzione hash sommi ogni byte di dati e se i dati erano pari, il valore di hash è 0. Se i dati erano dispari, l'hash è 1.

Capisci perché non hai potuto recuperare i tuoi dati dal reverse engineering di quella funzione hash?

È lo stesso per gli attuali algoritmi di hash, solo le formule sono significativamente migliori della funzione che ho appena descritto.

La tua difficoltà potrebbe essere che stai considerando l'hash per quanto riguarda il loro uso per le password. Non è ovvio il motivo per cui non è possibile recuperare una password di 8 caratteri da un hash a 128 bit. Ma quella funzione hash che usi per le password può anche essere usata per calcolare l'hash di un intero terabyte di dati e l'hash prenderà comunque solo 128 bit di dati. Ovviamente, non puoi decodificare quell'hash a 128 bit e recuperare il tuo terabyte di dati.

Inoltre, supponendo che tu abbia avuto ogni possibile permutazione di un singolo terabyte di dati, ci sarebbe un'enorme quantità di dati diversi che generano lo stesso hash. Dopotutto, se si hanno più di 2 ^ 127 diverse permutazioni di dati, è probabile che si verifichino due dati diversi con lo stesso hash.

8
user1068775

Esistono algoritmi intrinsecamente non reversibili; cambiano un input A in un output B in modo tale che anche se si conoscono i passaggi esatti dell'algoritmo, non è possibile recuperare A da B.

Un esempio molto semplice: converti ogni carattere nella password nel suo valore ASCII e somma tutti i valori. Non è possibile recuperare la password originale dal risultato.

4
Massimo

C'è un aspetto del problema che le persone mancano nelle risposte precedenti. Questa è la natura molti-a-uno delle funzioni hash. Poiché (la maggior parte) le funzioni hash sono output a lunghezza fissa (ad es. 256 bit), tecnicamente ci sono infinite stringhe che hanno tutti lo stesso valore.

Ad esempio, se prendi tutte le stringhe da 512 bit (di cui ci sono 2 ^ 512). Ci sono solo 2 ^ 256 uscite della funzione hash. Pertanto, per ogni output della funzione hash, ci sono circa 2 ^ 256 stringhe da 512 bit che hanno hash a quel valore. Dico all'incirca perché non sappiamo se la funzione hash sia effettivamente una funzione casuale, potrebbe avere lievi distorsioni.

Quindi, dato un riassunto, ci sono molte stringhe che hanno lo stesso valore. Pertanto, se si definisce "inversione di una funzione hash" come emissione della password dell'utente, in che modo la funzione di inversione gestirà il numero potenzialmente infinito di stringhe che generano il dato digest?

2
mikeazo

Stai chiedendo "perché è importante che le funzioni hash siano a senso unico?" È una proprietà di sicurezza.

Esistono due tipi di "hash" (o "digest dei messaggi" come vengono chiamati) oggi in uso comune. Uno è un semplice digest di messaggi, che potresti avere familiarità con un algoritmo di checksum, come CRC32. L'algoritmo è progettato in modo tale che un singolo cambio di bit nell'input produca un valore digest diverso. Lo scopo principale di questo è garantire che un messaggio non sia stato danneggiato per errore. I checksum CRC32 sono presenti su ogni pacchetto TCP/IP e una mancata corrispondenza comporta la ritrasmissione per correggere l'errore.

I digest dei messaggi vengono spesso utilizzati nella crittografia come parte della "firma" di un messaggio. Il messaggio è crittografato dal mittente con la sua chiave privata e chiunque può utilizzare la chiave pubblica per confermare che è stato crittografato solo dal mittente. Ma la crittografia a chiave pubblica RSA può crittografare solo i messaggi più piccoli della dimensione della chiave (256 byte), che sono molto più brevi della maggior parte dei messaggi utili. Gli algoritmi di digest dei messaggi producono valori inferiori alle chiavi RSA. Quindi, crittografando il digest anziché il messaggio, le firme RSA possono essere utilizzate su messaggi di qualsiasi dimensione.

Ma un normale digest dei messaggi non è sicuro contro un aggressore. Considera un checksum molto semplice che somma semplicemente i valori dei caratteri. Se firmassi un tale checksum, potrei scambiare qualsiasi altro messaggio che produca lo stesso checksum e le firme corrisponderebbero, ingannando la vittima.

Un altro uso comune dei digest dei messaggi è la protezione tramite password durante la memorizzazione. Se si crittografano le password prima di memorizzarle nel sistema, un amministratore di sistema che conosce la chiave potrebbe decrittografarle tutte. (Potresti aver notato questo problema di recente quando alcuni siti Web sono stati hackerati.)

Per evitare questi problemi, è necessario un diverso tipo di hash, uno che sia "crittograficamente sicuro". Un algoritmo di hash sicuro ha due proprietà aggiuntive, resistenza alla collisione e non reversibilità.

La resistenza alla collisione significa che non dovrei riuscire a trovare un messaggio che produca lo stesso digest. In questo modo non posso scambiare il mio messaggio malvagio con il tuo buon messaggio.

La proprietà di non reversibilità significa che non riesco a trasformare un digest in un testo in chiaro, quindi non posso decrittografare il messaggio originale, come la password dell'utente.

La creazione di un digest è un problema molto simile alla crittografia, in quanto è necessario mescolare i dati in modo tale da non perdere informazioni sui dati originali. È ancora più difficile, perché la stessa matematica non deve fornire alcun indizio su come creare con successo una collisione.

1
John Deters

Penso che ci siano molte ragioni, ma una è ovvia: un digest prodotto da una funzione hash non può mai contenere informazioni infinite, poiché il digest ha bit finiti. Ma la funzione hash può essere usata per inserire hash di informazioni infinite. L'input può effettivamente essere qualsiasi cosa.

La difficoltà a scoprire una collisione non è la risposta. La vera difficoltà sta dimostrando che i tuoi dati originali sono in realtà l'unico input possibile che corrisponde a un determinato digest. Penso che potresti non calcolare mai un input e affermare che è l'unica risposta al digest.

0

Altri hanno spiegato perché le buone funzioni di hash crittografico sono difficili da invertire - ma secondo questo articolo di Wikipedia , LanMan è mal progettato e può essere invertito relativamente facilmente:

Sebbene sia basato su DES, un codice di blocco ben studiato, l'hash LM non è una vera funzione unidirezionale poiché la password può essere determinata dall'hash a causa di diversi punti deboli nella sua implementazione ... Montando un attacco di forza bruta su ogni metà separatamente, le moderne macchine desktop possono rompere gli hash LM alfanumerici in poche ore ... Nel 2003, è stata pubblicata Ophcrack, un'implementazione della tecnica del tavolo Rainbow. Si rivolge in modo specifico ai punti deboli della crittografia LM e include dati pre-calcolati sufficienti per rompere praticamente tutti gli hash alfanumerici LM in pochi secondi.

0
James