C'è qualcosa di diverso nella sicurezza di questi due algoritmi di hashing? HMAC "fonde" i dati e la chiave in un modo speciale che è più sensibile alla sicurezza?
C'è qualcosa di diverso nella sicurezza di questi due algoritmi di hashing? HMAC "fonde" i dati e la chiave in un modo speciale che è più sensibile alla sicurezza?
Sì, HMAC è più complesso di una semplice concatenazione.
Come esempio semplicistico, se dovessi semplicemente concatenare chiavi + dati, quindi "chiave1" + "dati" restituisce risultati identici a "chiave" + "1data", che è subottimale. HMAC produrrà risultati diversi per ciascuno. Ci sono anche altri difetti con concatenazione semplice in molti casi; guarda la risposta di cpast per uno.
Le specifiche per HMAC si chiamano RFC2104 , che dovresti leggere se hai questo livello di interesse.
In breve, per implementare HMAC, devi prima:
Crea "ipad", che è 0x36
ripetuto volte BLOCKSIZE.
Crea "opad", che è 0x5c
ripetuto volte BLOCKSIZE.
Quindi HMAC è definito come:
HASH(Key XOR opad, HASH(Key XOR ipad, text))
o, in dettaglio da RFC,
(Pretext: The definition of HMAC requires a cryptographic hash function, which we denote by H, and a secret key K. We assume H to be a cryptographic hash function where data is hashed by iterating a basic compression function on blocks of data. We denote by B the byte-length of such blocks.)
(1) append zeros to the end of K to create a B byte string
(e.g., if K is of length 20 bytes and B=64, then K will be
appended with 44 zero bytes 0x00)
(2) XOR (bitwise exclusive-OR) the B byte string computed in step
(1) with ipad
(3) append the stream of data 'text' to the B byte string resulting
from step (2)
(4) apply H to the stream generated in step (3)
(5) XOR (bitwise exclusive-OR) the B byte string computed in
step (1) with opad
(6) append the H result from step (4) to the B byte string
resulting from step (5)
(7) apply H to the stream generated in step (6) and output
the result
In realtà c'è un grosso problema con SHA256(key||data)
: SHA-256, insieme a SHA-512, SHA-1, MD5 e tutti gli altri hash che usano la costruzione Merkle-Damgård, è vulnerabile a un lunga estensione attacco: dato H(x)
, è molto semplice trovare H(x||y)
, anche se conosci solo la lunghezza di x
, perché di come funziona la costruzione.
(Essenzialmente, la costruzione funziona così: hai una variabile state
che inizia con un valore fisso specificato nell'algoritmo. Hai diviso l'input della funzione hash in blocchi di dimensione specificati nell'algoritmo (riempire l'ultimo se è troppo corto), e per ogni blocco, si usa il blocco corrente e l'attuale state
per calcolare il nuovo state
utilizzando una funzione speciale specificata nell'algoritmo.Il valore di state
dopo l'elaborazione dell'ultimo blocco è il valore dell'hash. Con qualsiasi funzione che utilizzi questa costruzione, se hai la lunghezza di x
, puoi calcolare il padding p
usato, quindi se hai H(x)
, hai lo stato dopo l'elaborazione di ogni blocco di x||p
, il che significa che puoi procedere da lì a calcolare H(x||p||y)
).
Ciò significa che un utente malintenzionato che conosce la lunghezza della tua chiave MAC e conosce un particolare valore di SHA256(key||data)
può facilmente calcolare SHA256(key||data||otherdata)
per un dato otherdata
. Possono scegliere la maggior parte degli altri dati, ma anche se non ci riescono, è un difetto fatale in uno schema MAC se un utente malintenzionato senza la chiave può falsificare qualsiasi coppia di dati MAC da altri MAC legittimi- coppie di dati.
Per inciso, SHA256(data||key)
, pur non essendo vulnerabile all'estensione di lunghezza, è vulnerabile alle collisioni in SHA256
, che può anche produrre collisioni nel MAC proposto, a causa della stessa costruzione iterata. La nidificazione di HMAC previene questi e altri attacchi. Con gli hash non Merkle-Damgård, però, non hai necessariamente bisogno della costruzione HMAC.
Leggi altre domande sui tag hmac