You are on page 1of 16

TEHNIKO VELEUILITE U ZAGREBU SPECIJALISTIKI STRUNI DIPLOMSKI STUDIJ INFORMATIKE

SEMINAR

Programsko rjeenje primjera HASH algoritma za kriptiranje


Zoran Soptija Voditelj: Miroslav Slami

Zagreb, travanj 2013.

1. Uvod
HASH funkcije koriste algoritme koji komprimiraju niz proizvoljno velikih ulaznih bitova u niz bitova ksne veliine. One nisu randomizirajue funkcije, ve se od njih oekuje da za isti ulazni podatak uvijek daju isti izlaz kojeg nazivamo hash. Ako dva ulazna podatka generiraju isti hash, postoji snana pretpostavka da su podatci isti. Dakle moemo rei da hash kraim podatkom predstavlja vei, pa hash-eve moemo usporediti sa otiscima prstiju. Vrlo jednostavan za razumijevanje (mada i neprihvatljiv1 ) primjer HASH funkcije jest modulo operacija. Ulaz(2) Operacija Rezultat(10) Rezultat(2) 00110010 00110011 ... 00111100 50 mod 50 50 mod 51 ... 60 mod 50 0 1 ... 10 0000 0001 ... 1010

00111101 61 mod 50 11 1011 Primjerice ime osobe predstavljeno nizom ASCII kodova moemo pretvoriti u 8-bitni broj. Na doljnjem Python kodu prikazana je jednostavna rotacijska HASH funkcija, kao primjer minimalne adekvatne HASH funkcije2 :

1 2 3 4 5

def hash ( ulaz ): stanje = 0 for i , x in enumerate ( ulaz ): stanje = ( stanje << 4) ^ ulaz [ i ] ^ stanje ^ ( stanje >> 2) return stanje

Gornja HASH funkcija kao ulaz prima proizvoljno velik ASCII string i vraa osmobitni HASH. Na treoj liniji for petlja uzima svaki byte ulaza koji se na
1 2

Julienne Walker, http://eternallyconfuzzled.com Julienne Walker, http://eternallyconfuzzled.com

etvrtoj liniji koristi da bi uz pomo prethodnog stanja i XOR operacije promijenio unutarnje stanje funkcije. Nakon onoliko koraka koliko string ima byteova, funkcija vraa svoje unutarnje stanje koje se koristi kao hash. Jedna od primjena HASH funkcija su HASH tablice. Da bi to bolje shvatili korisnost HASH funkcija opisat u rad HASH tablica. HASH tablice se koriste za implementaciju strukutura podataka kao to su polja. Polja sadre indekse, i vrijednosti koje se nalaze svaka na lokaciji oznaenoj tim indeksom. HASH funkcija se koristi za generiranje indeksa. Na slici 1.2 je dan primjer HASH tablice, sa imenima osoba i njihovim telefonskim brojevima. U sluaju kada bi za pretraivanje koristili obinu for petlju i usporeivanje stringova, vrijeme pretraivanja u najgorem sluaju, izraeno Big O notacijom bilo bi O(n) gdje n predstavlja broj elemenata. Koristei HASH tablice mapiranje je 1:1 te je vrijeme pretraivanja O(1) to je najbolji mogui scenario. Ovo je znaajno ubrazanje prilikom pretraivanja velikih baza podataka. Veina hash funkcija je surjektivna. Zbog toga se javlja pojam kolizije. Kolizija je nepoeljna pojava i javlja se u sluaju kad dva razliita ulaza generiraju isti hash. Vjerojatnost pojave kolizija moemo promatrati kroz "Paradoks roendana", pojma iz matematike teorije vjerojatnosti koji denira koja je vjerojatnost da u grupi od n ljudi dvoje ima isti roendan. Tako je za grupu od 367 ljudi vjerojatnost da dvoje ima isti roendan 100 posto. Pojava kolizija ovisi o broju ulaznih podataka, te veliini hash-a. Na slici 1.3 dana je vjerojatnost pojave kolizija. Uz koritenje HASH-a odgovarajue veliine, za broj ulaznih podataka koji e se koristiti, pojava kolizija se dodatno smanjuje: Koritenjem "savrenih HASH funkcija" Kvalitetnim dizajniranjem HASH funkcija Savrene HASH funkcije se koriste u sluajevima kada je broj ulaza unaprijed poznat. U tom sluaju svaki od ulaza daje jedinstven hash, funkcija je injektivna i kolizije ne postoje. Da bi se broj kolizija smanjio na minimum, otealo namjerno traenje kolizija, te kako bi se polje moguih hash-eva to ravnomjernije popunjavalo hash funkcije se dizajniraju tako da promjena u samo jednom bitu ulaza, daje drastinu promjenu kroz cijeli spektar bitova hash-a. Ova znaajka dizajna se zove "efekt lavine".

Pero

HASH funkcija

90

Pero Peric

HASH funkcija

67

Slika 1.1: Ilustracija rada jednostavne HASH funkcije

1 Pero Miri HASH funkcija Pero Peri 2 ... 67 ... 90 91


Slika 1.2: Ilustracija HASH tablice

... 221-332 ... 223-221

Pero

HASH funkcija

90

Pero Peri

HASH funkcija

67

Pero Perievi HASH funkcija


Slika 1.3: Hipotetski primjer kolizije

Slika 1.4: Vjerojatnost pojave kolizije, ovisno o veliini i broju hash-eva

2. Openito o HASH algoritmima za kriptiranje


Do sada smo mogli vidjeti da kao minimum HASH funkcije posjeduju dva svojstva: Lako izraunavanje digesta za bilo koju ulaznu poruku. Ako je dana hash funkcija h, i ulaz x, h(x) je lako izraunati Komprimiranje. HASH funkcija h mapira ulaz x na izlaz h(x) konane i ksne duljine bitova Kriptografske funkcije za izraunavanje saetka imaju mnogo primjena u informacijskoj sigurnosti, a najvie u digitalnim potpisima, kodovima za autentikaciju poruke i drugim oblicima autentikacije. Takoer se primjenjuju za detekciju plagijata, identiciranje datoteka i kao kontrolna suma za provjeru sluajnog oteenja podataka. Zbog specinosti njihove primjene za njih je vano da budu otporne na sve poznate kriptoanalitike napade te, da kao minumum posjeduju slijedea dodatna svojstva: Otpornost1 na izraunavanje neke ulazne poruke x ili originalne poruke x koja e dati poznati hash y . H ( x) = y (eng. preimage resistance) Otpornost2 na izraunavanje poruke x (drugog originala) koja e dati isti hash kao i poznata poruka x. x != x, H(x) = H(x) (eng. 2-nd preimage resistance) Otpornost3 na traenje bilo koje dvije poruke rnd(x), rnd(x ) koje e dati isti HASH, h(x) = h(x ) (eng. collision resistance)
Cijena izraunavanja mora biti >= 2n pokuaja kada se koristi ista raunalna sila. Cijena izraunavanja mora biti >= 2n kada se koristi ista raunalna sila. n 3 Cijena izraunavanja mora biti >= 2 2 kada se koristi ista raunalna sila. Ovdje je ci1 2

jena izraunavanja 2 2 jer se zbog traenja dvije poruke koje e dati isti hash njegov spektar prepolovljuje.

Ako HASH funkcija zadovoljava prve dvije znaajke, naziva se jednosmjernom HASH funkcijom (OWHF), dok se HASH funkcija koja zadovoljava sve tri znaajke naziva otpornom na kolizije (CRHF). Otpornost na kolizije takoer podrazumjeva i otpornost na izraunavanje drugog originala. Pretpostavimo da je neka HASH funkcija h opisana kao otporna na kolizije. Ako napada posjeduje poruku x to podrazumjeva da moe posjedovati i njezin hash, te funkcija nije otporna na izraunavanje drugog originala, tada moemo nai poruku x koja e dati isti hash kao i poruka x. U tom sluaju imamo par (x, x ) koji daje isti hash, to je kontradikcija navedenoj otpornosti na kolizije.

2.1.

Konstrukcija kriptografskih HASH funkcija

Da bi ulaz proizvoljne duljine pretvorili u hash ksne duljine, metodologija dizajna HASH funkcija je takva da u vie navrata koriste funkcije koje rade sa malim podatcima ksne duljine. Stoga u HASH funkcijama proirujemo domenu navedenih manjih funkcija razbijanjem ulaza u hash funkciju na blokove duljine sa kojima one rade. Te funkcije su poznate kao kompresijske funkcije. Stoga se konstrukcija HASH funkcije sastoji od dvije glavne komponente: Kompresijske funkcije (mapira ulaz ksne duljine u izlaz ksne duljine) Proirivaa domene (koristi kompresijsku funkciju za stvaranje funkcije sa ulazom proizvoljne duljine i izlazom ksne duljine) Svaka kompresijska funkcija koja je otporna na kolizije moe se proiriti u HASH funkciju otpornu na kolizije, pa je zbog toga dizajn dobre kompresijske funkcije kljuan element izrade dobre HASH funkcije. Veina kompresijskih funkcija se temelji na algoritmima blok ifre. One se dodatno mogu podijeliti na kompresijske funkcije koje koriste poznate algoritme blok ifre kao to su DES i AES, i kompresijske funkcije koje su dizajnirane posebno za odreenu hash funkciju. Ove druge se nazivaju dedicirane kompresijske funkcije. Jo jedan pristup konstruiranju kompresijskih funkcija lei u koritenju poznatih matematikih problema, kao to je faktorizacija velikih brojeva. (digitalni potpis) Mogue je koristiti i algoritam protone ifre (engl. stream cipher) za dizajniranje hash funkcija. Ovakve funkcije tipino imaju blokove manje duljine i vei broj iteracija. Generalni pristup pri dizajniranju HASH funkcija je opisan na slijedei nain:

M = m1 , m2 , mn H0 = IV Hi = f (mi , Hi1 )zai = 1, 2, n h(x) = g(Hn ) M je ulazna poruka. m1 , m2 , mn jest ulazna poruka podjeljena na blokove ksne duljine prilagoene kompresijskoj funkciji. IV jest inicjalizacijski vektor. Funkcija f je kompresijska funkcija, a jedan od njenih ulaza jest hash iz prethodne iteracije. Hi je chaining value, a rezultat HASH funkcije je oznaen sa h(x). Ponekad se koristi i funkcija g ija je uloga da dodatno smanji duljinu hash-a.

2.1.1.

Merkle-Damgard konstrukcija

Jedan od najee koritenih, najelegantnijih, i u literaturi najbolje opisanih proirivaa domene jest Merkle-Damgard konstrukcija. Ona opisuje metodu graenja hash funkcija iz kompresijskih funkcija. Ova konstrukcija je dodatno atraktivna jer je HASH mogue dobiti streamingom tj. nije nuno imati cijeli ulaz u trenutku pokretanja algoritma. Na taj nain mogue je dobiti hash sa malom i ogranienom koliinom memorije hashirajui dio po dio. Nadograuje prethodni primjer pristupa dizajniranja HASH funkcija uz odreene specinosti. Ulaz se dijeli na mi blokova duljine n. Duljina n odgovara veliini ulaza u kompresijsku funkciju f . Da bismo dobili duljinu poruke koja omoguuje rastavljanje poruke na jednake blokove, poruka se proiruje. Nakon toga proirenoj poruci se dodaje binarna vrijednost duljine originalne poruke xi . Ovo se naziva Merkle-Damgard ojaanje, a konkretna izvedba bit e prikazana u slijedeem poglavlju. Svaki od blokova poruke mi slui kao ulaz u kompresijsku funkciju f koja vraa meuhash nakon izvravanja svojeg algoritma. Taj meuhash slui kao povratna veza prilikom raunanja meuhasha za slijedei blok xi+1 . To implicira da je potreban inicijalizacijski vektor za raunanje meuhasha prvog bloka poruke. Jedan od zahtjeva kod Merkle-Damagard konstrukcije jest da on bude dobro odabran.

Slika 2.1: Merkle-Damgard konstrukcja

3. Glavne karakteristike i analiza MD5 algoritma


HASH funkciju MD5 dizajnirao je Ron Rivest 1992. godine kao zamjenu za MD4. esto se opisuje kao MD4 sa dodatnim sigurnosnim znaajkama. Njen opis je dan u dokumentu RFC 1321. Uzima poruke proizvoljne veliine te vraa digest duljine 128 bita. Koristi Merkle-Damgard konstrukciju. Poruke se razdvajaju na blokove od 512 bita, te se koristi 128-bitni chainging value. Algoritam radi na slijedei nain: Poruka M se proiruje kako bi njena duljina bila viekratnik broja 512, na nain da se prvo dodaje 1(2) , i onoliko nula da bi poruka bila djeljiva sa 448. Zatim se na kraj dodaje duljina originalne poruke predstavljena sa 64 bita. Proirena poruka pad(M ) se dijeli na n blokova od 512 bita. pr. pad(M ) = m1 , m2 , m3 , mn ... Postavlja se 128-bitni inicijalizacijski vektor, koji se kasnijim manipulacijama koristi kao unutarnje stanje (chaining value) na defaultne vrijednosti, koja se tretira kao 4 odvojene 32-bitne rijei. h0 = [A = 67452301(16) , B = EF CDAB 89(16) , C = 98BADCF E(16) , D = 10325476(16) ] Unutarnje stanje se tretira na ovaj nain, jer je algoritam prilagoen za 32-bitna raunala. Za svaki meuhash hn primjenjuje se kompresijska funkcija Hn (hn1 , mn ) MD5 kompresijska funkcija radi na slijedei nain: Sastoji se od 64 iteracije. Iteracije su podjeljenje na 4 runde, a svaka runda se sastoji od 16 slinih operacija. Neka je hn1 = (A0, B 0, C 0, D0) i neka je jedan 512-bitni blok poruke Mn = (W 0, W 1, W 2, ..., W 15)

Od n = 0 do n = 64 izvrava se slijedei pseudokod: temp = Dn Dn = C Cn = B n Bn = Bn + (An + fn (Bn , Cn , Dn ) + Kn + Wg(n ) ) sn An = temp Na kraju obrade trenutnog bloka kompresijskom funkcijom, dobiva se meuhash: hn = (A0 + A64 , B0 + B64 , C0 + C64 , D0 + D64). Za svaku rundu od 16 iteracija koristi se drugaija funkcija, drugaija konstanta, drugaija konstanta za rotaciju, i drugaija 32-bitna rije poruke. Na kraju svakog bloka se rauna novi meuhash h koji se koristi kao chaining value za slijedei 512-bitni blok proirene poruke. Runda Funkcija 0 <= n, <= 15: 16 <= n, <= 31: 32 <= n, <= 47: 47 <= n, <= 63: fn (X,Y,Z) = XY AND (NOT X)Z fn (X,Y,Z) = XY AND (NOT Z)X fn (X,Y,Z) = X XOR Y XOR Z fn (X,Y,Z) = Y XOR (X AND NOT Z) 32-bitna rije g(n) = n g(n) = (5n +1) mod 16 g (n) = (3n) mod 16 g (n) = (7n) mod 16

Konstanten se konstruiraju na osnovu sin funkcije, a rotacijske konstante Sn za svaku od 64 iteracija su dane u doljnoj tablici. 7 5 4 6 12 9 11 10 17 14 16 15 22 20 23 21 7 5 4 6 12 9 11 10 17 14 16 15 22 20 23 21 7 5 4 6 12 9 11 10 17 14 16 15 22 20 23 21 7 5 4 6 12 9 11 10 17 22 14 20 16 23 15 21

10

4. Primjena MD5 algoritma


MD5 se danas smatra razbijenom HASH funkcijom. Ovo se najvise odnosi na njenu otpornost na kolizije. Godine 2005. grupa istraitelja je uspjela kontstruirati par PostScript dokumenata i X.509 certikata koji daju isti HASH. Mogue je traiti kolizije sa kompleksnou od 224.1 pokuaja. to znai da je traenje kolizije na raunalu Pentium 4 sa radim taktom od 2.6GHz mjeri u vremenu od nekoliko sekundi. Ovo kri uvijet otpornosti na kolizije 2 2 , stoga MD5 vie nije zadovoljavaju za primjene kao to su provjera autentinosti dokumenata. Bez obzira na ovu injenicu MD5 se i dalje koristi za verikaciju preuzetih datoteka sa interneta, dodue uz dodatne saetke drugih HASH funkcija. Budui da jo
n

Slika 4.1: Datoteka sa MD5 hashevima kod preuzimanja operacijskog sustava Ubuntu

ne postoji praktian nain za izraunavanje prvog originala MD5 hash-a, MD5 se koristi u sustavima autentikacije lozinkom, gdje je MD5 hash lozinke spremljen u bazi podataka, te se prilikom svakog logiranja korisnika rauna hash lozinke i usporeuje sa onim iz baze.

11

5. Programsko rjeenje algoritma


Programsko rijeenje algoritma u Python 3.2 jeziku.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 const = [ math . floor ( abs ( math . sin ( x +1)) * math . pow (2 ,32))\ &0 xFFFFFFFF for x in range (64)] word_select =[ lambda i : i ,\ lambda i : (5* i + 1)%16 ,\ lambda i : (3* i + 5)%16 ,\ lambda i : (7* i )%16] functions = [ lambda x ,y , z : x & y lambda x ,y , z : ( x & z ) | ~ x & z ,\ | ( y & ~ z ) ,\ def digest ( self ): shift = [7 , 12 , 17 , 22 , 7 , 12 , 17 , 22 , 7 , 12 , 17 , 22 , 7 , 12 , 17 , 22 , 5, 9 , 14 , 20 , 5 , 9 , 14 , 20 , 5 , 9 , 14 , 20 , 5 , 9 , 14 , 20 , 4 , 11 , 16 , 23 , 4 , 11 , 16 , 23 , 4 , 11 , 16 , 23 , 4 , 11 , 16 , 23 , 6 , 10 , 15 , 21 , 6 , 10 , 15 , 21 , 6 , 10 , 15 , 21 , 6 , 10 , 15 , 21] message = message + len_of_me ssage . to_bytes (8 , byteorder = " little " ) self . message = message def _padding ( self , message ): message = bytearray ( message ) len_o f_messag e = 8* len ( message ) message . append (0 x80 ) # dodaje byte 1000 0000 while len ( message )*8 message . append (0) # poruka mora biti mora biti 64 bita manja od m n o z i t e l j a 512. self . _padding ( message ) class MyMD5 ( object ): def __init__ ( self , message ): self . constants = { " A " : 0 x67452301 , " B " : 0 xefcdab89 ,\ " C " : 0 x98badcfe , " D " : 0 x10325476 } self . _ g e t _ i n i t _ c o n s t a n t s = lambda : dict ( self . constants ) import math

lambda x ,y , z : x ^ y ^ z ,\ lambda x ,y , z : y ^ ( x | ~ z )]

12

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90

def rotate ( wrd , rotate ): wrd &= 0 xFFFFFFFF return (( wrd < < rotate ) | ( wrd > >(32 - rotate ))) & 0 xFFFFFFFF def _update_state ( word ): for key in word . keys (): self . constants [ key ] += int ( word [ key ]) self . constants [ key ] &= 0 xFFFFFFFF return self . constants message = self . message for big_chunk in range (0 , len ( message ) , 64): word = self . _ g e t _ i n i t _ c o n s t a n t s () for i in range (64): if i <= 15: f = functions [0]( word [ " B " ] , word [ " C " ] , word [ " D " ]) g = word_select [0]( i ) if i >= 16 and i <= 31: f = functions [1]( word [ " B " ] , word [ " C " ] , word [ " D " ]) g = word_select [1]( i ) if i >= 32 and i <= 47: f = functions [2]( word [ " B " ] , word [ " C " ] , word [ " D " ]) g = word_select [2]( i ) if i >= 48 and i <= 63: f = functions [3]( word [ " B " ] , word [ " C " ] , word [ " D " ]) g = word_select [3]( i ) temp = word [ " D " ] word [ " D " ] = int ( word [ " C " ]) word [ " C " ] = int ( word [ " B " ]) word [ " B " ] = word [ " B " ] + rotate ( word [ " A " ] + f + const [ i ]\ + int . from_bytes ( chk_16_32 [ g ] , byteorder = " little " ) ,\ shift [ i ]) & 0 xFFFFFFFF word [ " A " ] = int ( temp ) _update_state ( word ) hash_hex = bytes () for key in [ " A " , " B " , " C " , " D " ]: hash_hex += bytes ( self . constants [ key ]. to_bytes (4 , byteorder = " little " )) print ( hash_hex ) print ( {:032 x } . format (( int . from_bytes ( hash_hex , byteorder = " big " ))))

chk_16_32 =[ message [ byte : byte +4] for byte in range ( big_chunk , big_chunk +64 ,4)] # r a s t a v l

if __name__ == " __main__ " : input = input ( " upisite poruku za hashiranje MD5 algoritmom : " ) message = bytearray ( input ). encode ( " ascii " )) hash = MyMD5 ( message ) print ( " Hash je : " , hash . digest ())

13

6. Zakljuak
Iako MD5 ima vrlo dobro dokumentirane ranjivosti, te su za njegovu zloupotrebu dostupni gotovi alati (pr. Evilize sa kojim moemo kompajlirati dva programa razliita u jednoj funkciji, a koji daju isti MD5 hash) on je i dalje u upotrebi. Jedan od razloga je i njegova brzina. Primjerice moe se koristiti u sistemu provjere dali se datoteka koju elimo downloadati promijenila ili moemo koristiti kopiju iz cache-a. Brzina je bitan faktor na ureajima koji su ogranieni u svojim resursima i potreban im je HASH algoritam zbog provjere integriteta podataka i sl. Drugi razlog daljnjeg koritenja ovog algoritma jest njegova rasprostranjenost. Takoer, hash od 128-bita je relativno kratak i lak za raspoznavanje. Budui da ne postoji praktian nain za dolaenje do prvog originala MD5 HASH-a, relativno je siguran za koritenje u sustavima za autentikaciju lozinkom. Uz dodavanje salt-a, ta sigurnost se dodatno poveava. U ve uhodanim sistemima, sa srednjim zahtjevima vezanim za sigurnost, MD5 se i dalje moe koristiti, budui da su svi napadi na njega ogranieno iskoristivi. Uz prolazak godina MD5 e se koristiti sve manje, budui da e se zbog same duljine saetka od 128 bita praktino moi izvesti napad istom raunalnom silom. to se tie sistema sa velikim sigurnostnim zahtjevima kao to su primjerice SSL certikati preporuka je koritenje SHA-2 algoritma.

14

7. Literatura
[1] Orr Dunkelman: Hash Functions - MD5 and SHA1, 14. 3. 2012. [2] R. Rivest: The MD5 Message-Digest Algorithm, April 1992: RFC132 [3] Hash collision probabilities, 30. 3. 2013: http://preshing.com/20110504/hash-collision-probabilities [4] Cryptographic hash function, 30. 3. 2013: http://en.wikipedia.org/ [5] Jullienne Walker Eternally Confuzzled - The art of hashing, 30. 3. 2013: http://eternallyconfuzzled.com/tuts/algorithms/ [6] Hash Function Tutorial, 30. 3. 2013: http://www.uow.edu.au/ jennie/CSCI971/hash1.pdf [7] Wikipedia Hash Table, 30. 3. 2013: http://en.wikipedia.org [8] One-way compression function, 30. 3. 2013: http://en.wikipedia.org [9] Wikipedia MD5, 30. 3. 2013: http://en.wikipedia.org [10] MD5 Collisions, 30. 3. 2013: http://www.cits.rub.de/MD5Collisions/ [11] Cryptographic Hashes, 30. 3. 2013: http://vpnc.org/hash.html [12] Monika eri Diplomski rad: Programsko ostvarenje algoritama BLAKE, Shabal i SIMD, sijeanj 2011: FER [13] Anupam Pattanayak Revisiting Dedicated and Block Cipher based Hash Functions, 30. 3. 2013: Computer Science Engineering Department, Haldia Institute of Technology, Haldia, India [14] Michal Rjako Diplomski Rad: Properties of Cryptographic Hash Functions, 2008: Faculty of Mathematics, Physics and Informatics, Department of Computer Science 15

You might also like