it-swarm.it

Perché AES non viene utilizzato per l'hash sicuro, invece di SHA-x?

A quanto ho capito, AES è ritenuto estremamente sicuro. (Ho letto da qualche parte che non sarebbe certamente rotto nei prossimi 20 anni, ma non sono ancora sicuro che l'autore fosse serio.)

DES non è ancora così male per un vecchio cifrario e 3DES è ancora usato (forse non così tanto, ma almeno vedo 3DES in: configurazione in Firefox).

Sembra che i (buoni) blocchi cypher siano ritenuti affidabili dalla community di criptovalute.

OTOH, vengono scoperti molti problemi con le funzioni hash crittografiche.

Dal punto di vista dello specialista non crittografico: le funzioni di hashing e i cifrari simmetrici sono la stessa cosa: una funzione "casuale" (con input e output diversi).

Quindi, perché non usare solo AES per l'hashing? Queste sembrano le cose ovvie da fare per ottenere la forte sicurezza di AES per l'hashing. Come bonus, potrebbero essere utili le implementazioni hardware di AES?

C'è una semplice spiegazione della vera differenza tra le funzioni hash e i cifrari simmetrici?

46
curiousguy

Una cifra di blocco ha una chiave; la segretezza della chiave è ciò su cui si basa la sicurezza della crittografia. D'altra parte, una funzione hash non ha alcuna chiave e non ci sono "dati segreti" su cui costruire la sicurezza della funzione hash.

Un codice a blocchi è reversibile: se conosci la chiave, puoi decifrare ciò che è stato crittografato. Tecnicamente, per una determinata chiave, una cifra di blocco è un permutazione dello spazio dei possibili valori di blocco. Le funzioni hash sono intese come non reversibili e non sono in alcun modo permutazioni.

Un codice a blocchi funziona su blocchi di dimensioni fisse (blocchi a 128 bit per AES), sia per l'ingresso che per l'uscita. Una funzione hash ha un output di dimensioni fisse, ma dovrebbe accettare input arbitrariamente grandi.

Quindi i cifrari a blocchi e le funzioni hash sono animali veramente diversi; piuttosto che cercare di differenziarli, è più facile vedere cosa hanno in comune: vale a dire che le persone che sanno come progettare un codice a blocchi sono anche ragionevolmente brave a progettare funzioni hash, perché gli strumenti matematici di analisi sono simili (piuttosto un molte algebre lineari e funzioni booleane, davvero).

Andiamo per definizioni più formali:

Una cifra di blocco è una famiglia di permutazioni selezionata da una chiave. Consideriamo lo spazio [~ # ~] b [~ # ~] of n - blocchi di bit per un valore fisso di n; la dimensione di [~ # ~] b [~ # ~] è quindi 2n. Le chiavi sono valori di uno spazio [~ # ~] k [~ # ~], in genere un altro spazio di sequenze di m bit ( m non è necessariamente uguale a n). Una chiave k seleziona una permutazione tra 2n! possibili permutazioni di [~ # ~] b [~ # ~].

Un codice a blocchi è considerato sicuro purché indistinguibile dal punto di vista computazionale da una permutazione che è stata scelta in modo uniforme e casuale tra 2n! possibili permutazioni. Per modellarlo, immagina una situazione in cui un attaccante ha accesso a due scatole nere, una implementando il codice a blocchi con una chiave che l'attaccante non conosce e l'altra essendo una permutazione davvero casuale. L'obiettivo dell'attaccante è di dire quale è quale. Può far crittografare o decrittografare ogni casella qualunque dato desideri. Il possibile attacco è provare tutte le possibili chiavi (ci sono 2m tali chiavi) ne viene trovata solo una, che fornisce gli stessi valori di una delle caselle; questo ha un costo medio 2m-1 invocazioni del codice. A secure block cipher è uno di questi che questo attacco generico è il miglior attacco possibile.

L'AES è definito su blocchi a 128 bit ( n = 128) e chiavi a 128, 192 e 256 bit.

Una funzione hash è una singola funzione calcolabile, completamente definita, che accetta sequenze di bit di input di lunghezza arbitraria e genera valori di lunghezza fissa r (es. r = 256 bit per SHA-256). Non c'è chiave, nessuna famiglia di funzioni, solo una funzione unica che chiunque può calcolare.

Una funzione hash h è considerata sicura se:

  • Non è fattibile dal punto di vista computazionale trovare preimmagini: dato a r - valore in bit x, non è possibile trovare m tale che h (m) = x.
  • Non è fattibile dal punto di vista computazionale trovare seconde preimmagini: dato m, non è possibile trovare m ' distinto da m , tale che h (m) = h (m ').
  • È impossibile trovare collisioni computazionalmente: non è possibile trovare m e m ', distinti l'uno dall'altro, in modo che h ( m) = h (m ').

Esistono attacchi generici che possono trovare preimmagini, seconde preimmagini o collisioni, con costi, rispettivamente, 2r, 2r e 2r/2. Quindi la sicurezza effettiva può essere raggiunta solo se r è abbastanza grande da 2r/2 è un costo enormemente enorme. In pratica, ciò significa che r = 128 (una funzione hash a 128 bit come MD5) è non abbastanza.

In modo informale, è positivo che la funzione hash "assomigli" sia stata scelta in modo casuale e uniforme tra le possibili funzioni che accettano gli stessi input. Ma questa è una proprietà mal definita poiché stiamo parlando di una funzione unica (le probabilità sono sempre implicitamente su medie ed esperienze ripetute; non puoi davvero avere probabilità con una singola funzione). Inoltre, essere una funzione casuale non è esattamente lo stesso di essere resistente a collisioni e preimmagini; questo è il dibattito sul Random Oracle Model .


Tuttavia, è possibile creare una funzione hash da un codice a blocchi. Questo è ciò che fa la costruzione Merkle-Damgård . Ciò comporta l'utilizzo del messaggio di input come tasto del codice a blocchi; quindi il codice a blocchi non è usato affatto come doveva essere. Con AES, questo si rivela deludente:

  • Il risultato è una funzione hash con output a 128 bit, che è troppo piccolo per la sicurezza rispetto alla tecnologia disponibile nel 2011.
  • La sicurezza della funzione hash si basa quindi sull'assenza di attacchi con chiave correlata sul codice a blocchi. Gli attacchi con chiave correlata non hanno realmente alcun significato pratico su un codice a blocchi se usati per la crittografia; quindi, AES non è stato progettato per resistere a tali attacchi e, in effetti, AES has a alcuni punti deboli a tale riguardo - non è una preoccupazione per la crittografia, ma un grande preoccuparsi se AES deve essere usato in una costruzione Merkle-Damgård.
  • Le prestazioni non saranno buone.

La funzione Whirlpool hash è un design che si basa su una cifra di blocco ispirata da AES - non quella reale. Quella chiave di blocco ha una pianificazione delle chiavi molto migliorata (e più pesante), che resiste agli attacchi delle chiavi correlate e la rende utilizzabile come nucleo di una funzione hash. Inoltre, quel codice di blocco funziona su blocchi a 512 bit, non su blocchi a 128 bit. Whirlpool è ritenuto sicuro. Whirlpool è noto per essere molto lento, quindi nessuno lo usa.

Alcuni progetti di funzioni hash più recenti hanno tentato di riutilizzare parti dell'AES - per essere precisi, per utilizzare un'operazione interna che si associa bene alle istruzioni AES-NI quali sono i recenti processori Intel e AMD. Vedi ad esempio ECHO e SHAvite- ; queste due funzioni hanno ricevuto entrambe un bel po 'di visibilità nell'ambito della competizione SHA- e sono ritenute "ragionevolmente sicure". Ci sono molto veloci sui recenti processori Intel e AMD. Su altre architetture più deboli, dove le prestazioni della funzione hash hanno qualche possibilità di importare davvero, queste funzioni sono piuttosto lente.

Esistono altre costruzioni che possono rendere una funzione hash da un codice a blocchi, ad es. quello usato in Skein ; ma tendono anche a richiedere blocchi più grandi di quelli su cui è definito l'AES.

Riepilogo: non solo le cifrature a blocchi e le funzioni hash sono abbastanza diverse; ma l'idea di costruire una funzione di hash dall'AES risulta essere di dubbia validità. Non è facile e la dimensione del blocco AES limitata è il principale ostacolo.

70
Thomas Pornin

La risposta di base è che si tratta di diversi tipi di algoritmi. AES è un algoritmo chiave simmetrico. Non puoi usarlo nello stesso ruolo di RSA (un algoritmo a chiave pubblica) o SHA-256 (un algoritmo di hashing). Sono sistemi diversi progettati con proprietà e punti deboli molto diversi.

Tuttavia, ho fatto una pausa e ho pensato seriamente a questa idea per spiegarla oltre a dire "È così". Dopotutto, un hash in senso universale è una rappresentazione ripetibile di dati in una dimensione fissa o ridotta. AES può fornire ciò tramite la modalità CBC. Tuttavia, ci sono più proprietà in un hash sicuro che semplici riduzioni.

Un algoritmo di hashing sicuro è un sistema a senso unico. AES crittografa e decodifica allo stesso modo (cifra simmetrica) e puoi creare una mappatura 1-1 per ciascun blocco che cosa accadrà con una determinata chiave. A meno che i dati non siano concatenati e quindi in perdita, è possibile semplicemente decrittografare l '"hash" AES nei dati di origine.

Non si può ragionevolmente invertire un SHA diverso da provare diversi dati di input. Per i motivi per cui non è possibile utilizzare SHA-x per crittografare qualcosa, non è possibile utilizzare AES per hash qualcosa.

11
Jeff Ferland

C'è una semplice spiegazione della vera differenza tra le funzioni hash e i cifrari simmetrici?

  • Una cifra è reversibile, una funzione hash no
  • La lunghezza dell'output di un codice dipende dalla lunghezza dell'input; una funzione hash produce lo stesso output di lunghezza indipendentemente dall'input
  • Una modifica a bit singolo in qualsiasi punto di una funzione di hash crittografica produce un cambiamento a cascata (drammatico) nell'output di hash. Di regola, questo non è vero per le cifre.
  • Una cifra richiede una chiave, un hash no

Il design e lo scopo dei due sono fondamentalmente diversi e non sono intercambiabili.

9
tylerl

Puoi fondamentalmente trasformare qualsiasi cifratura a blocchi in una funzione hash usando Merkle-Damgard-construction e puoi fondamentalmente trasformare qualsiasi funzione hash in una cifratura a blocchi usando Feistel-networks se definisci la funzione Feistel F nel modo seguente.

F(half_block, round_key) = hash(concatenate(half_block, round_key))

Ma è abbastanza inefficiente (richiede molto tempo per il calcolo), poiché F è già costoso da calcolare (è un algoritmo iterativo che utilizza ad esempio 80 "round" interni nel caso di SHA-512) e per la struttura di Feistel, F stesso viene ripetuto più volte. Supponi di avere una rete Feistel a 20 stadi con una funzione di round F da 80 round, esegui 1600 "round" SHA-2 per blocco. Porta anche a blocchi di dimensioni piuttosto grandi (il doppio delle dimensioni dell'output della funzione hash), e. g. Crittografia a blocchi a 1024 bit se si utilizza SHA-512 come funzione hash.

Ma in pratica, non è necessariamente "insicuro". È solo che i "cifrari a blocchi" facilmente disponibili (piuttosto permutazioni pseudocasuali - non permutazione come nella permutazione di bit/byte, ma permutazione nel senso della mappatura biiettiva tra "tutti i possibili blocchi di input" e "tutti i possibili blocchi di output") sono molto più efficiente, più ampiamente usato e quindi più accuratamente analizzato per le proprietà di essere buone permutazioni pseudocasuali. Se hai il potere di calcolo da sprecare, usa SHA-512 in una rete Feistel come codice a blocchi. È probabile che almeno non sia meno sicuro di AES (a condizione che si aggiunga una buona pianificazione dei tasti per derivare i "tasti rotondi"), tuttavia occorreranno lotti di cicli della CPU per elaborare un blocco.

3
no.human.being

M. Abel ha ragione. Un altro esempio di AES usato come hash è AES-CBC o AES-PCBC.

https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Propagating_Cipher_Block_Chaining_.28PCBC.29

Se CBC o PCBC o persino CFB vengono eseguiti su un "file" con e senza errori, il blocco finale sarà diverso.

È inefficiente, ma può essere fatto. La logica è: "Se tutto ciò che hai è un martello, tutto sembra un chiodo". Lo stesso vale per AES. Potrebbero esserci modi migliori per l'hash, ma se tutto ciò che hai è AES. . .

0
aesuser