MHASH_MD5
Md5 je jednosměrná hashovací funkce, kteoru vyvinul Ronald Rivest z MIT (Massachusetts Institute of Technology) v roce 1991. Algoritmus hashovací funkce MD5 byl vyvinut, aby nahradil starší funkci MD4. Postupně bylo v této funkci nalezeno několik vad, ale funkce je stále používána. V roce 2004 byli nalezeny další závažnější bezpečnostní chyby, nicméně i přesto všechno je tato hashovací funkce stále velmi používaná a plnohodnotně se vyrovná například funkci SHA-1.
Md5 je jednosměrná hashovací funkce, kteoru vyvinul Ronald Rivest z MIT (Massachusetts Institute of Technology) v roce 1991. Algoritmus hashovací funkce MD5 byl vyvinut, aby nahradil starší funkci MD4. Postupně bylo v této funkci nalezeno několik vad, ale funkce je stále používána. V roce 2004 byli nalezeny další závažnější bezpečnostní chyby, nicméně i přesto všechno je tato hashovací funkce stále velmi používaná a plnohodnotně se vyrovná například funkci SHA-1.
Název MD5 vznikl z anglického Message-Digest algorithm 5 a v současné době je popsána v internetovém standartu RFC 1321. Hlavní využití této funkce spočívá v malých aplikacích, například pro ověřování hesel v databázi.
Při hashování je generována, na základě vstupních dat, Hash Value, která je většinou kratší než vstupní text, a je tvořena takovým způsobem, že je velmi nepravděpodobné aby některý další text generoval stejnou Hash Value. Pokud by i přesto měli dva různé vstupní řetězce stejnou Hash Value, jednalo by se o kolizi. Jestliže tedy pomocí této funkce vytvoříte hash pro dva podobné řetězce, musí být otisk plně odlišný.
1 2 3 4 5 |
$string1 = 'retezec, ktery je velmi dlouhy musi byt po pouziti hashovaci funkce md5 naprosto k nerozeznani s retezcem ktery je tomuto retezci podobny.'; $string2 = 'aetezec, ktery je velmi dlouhy musi byt po pouziti hashovaci funkce md5 naprosto k nerozeznani s retezcem ktery je tomuto retezci podobny.'; print md5($string1) . '<br />'; print md5($string2) . '<br />'; |
Všimněte si, že řetězce na vstupu jsou téměř identické. Na výstupu musíme ale dostat dva maximálně odlišné řetězce:
1 2 |
97eb7a5231decd619f6157538cca7f89 bf6df6e02959e5c709d5c94f50643a97 |
Jak MD5 pracuje
MD5 vždy pracuje s daty, která mají celkovou délku v bitech násobku 512-ti. Pokud není velikost násobkem tohoto čísla, musí se doplnit na požadovanou velikost.
Doplňuje se následně:
– jeden byt hodnoty 1 je přidán tak, že délka zprávy je o 64 bitů menší než je konečný násobek 512
– chybějících 64 bytů má potom své uplatnění jako uchování délky zprávy pře doplněním, aby nebyla toto informace stracena.
Doplňování se provádí vždy, tedy i v případě, že je velikost násobkem 512-ti.
Když je vstupní řetězec upraven, nic nám nebrání zjistit Value hodnotu:
Tato hodnota závisí na opakované modifikaci 128-bitové hodnoty popisující stav.
Pro zpracování každého 128-bitového stavu je tento stav rozdělen na 4 bloky po 32 bitech, označených A, B, C, D a na začátku se každému z nich nastaví výchozí hodnoty.
Každý z techto 4 bloků je potom zpracován nezávisle na ostatních a různě modifikován, přičemž modifikace probíhají ve 4 stupních, které se nazývají kola. Jednotlivá kola se skládají z 16 operací, což je celkem (4*16) 64 operací pro každý blok dat.512-bitový blok dat je rozdělen na 16 datových slov. (každé obsahuje 32 bitů) a uvnitř každého kola je jedna z následujících operací:
1 2 3 4 |
F(X, Y, Z) = (X AND Y) OR (NOT(X) AND(Z)) G(X,Y,Z) = (X AND Z) OR (Y AND NOT(Z)), H(X,Y,Z) = X XOR Y XOR Z, I(X,Y,Z) = Y XOR (X OR NOT(Z)). |
Každá z těchto funkcí má jako vstupní parametr tři 32 bitové slova a návratová hodnota je pak jedna 32 bitová hodnota.
Tyto operace probíhají v každém kole a bloky A, B, C, D jsou postupně modifikovány. V závislosti na počátečním vstupu jsou využita k vypočtení koncové Value Hodnoty. Výsledek každého stupně je použit pro výpočet v dalším stupni.
Jak jsme si již řekli, v ideální hashovací funkci nesmí docházet ke kolizím. Bohužel ve funkci MD5 ke kolizím dochází.
V roce 2004 byl vytvořen algoritmus čínskými vědci, který hledal kolize.
Algoritmus sice zveřejněn nebyl, ale byl zveřejněn kolizní řetězec:
1 2 3 4 5 6 7 8 |
d131dd02 c5e6eec4 693d9a06 98aff95c 2fcab587 12467eab 4004583e b8fb7f89 55ad3406 09f4b302 83e48883 2571415a 085125e8 f7cdc99f d91dbdf2 80373c5b 960b1dd1 dc417b9c e4d897f4 5a6555d5 35739ac7 f0ebfd0c 3029f166 d109b18f 75277f79 30d55ceb 22e8adba 79cc155c ed74cbdd 5fc5d36d b19b0ad8 35cca7e3 |
1 2 3 4 5 6 7 8 |
d131dd02 c5e6eec4 693d9a06 98aff95c 2fcab507 12467eab 4004583e b8fb7f89 55ad3406 09f4b302 83e48883 25f1415a 085125e8 f7cdc99f d91dbd72 80373c5b 960b1dd1 dc417b9c e4d897f4 5a6555d5 35739a47 f0ebfd0c 3029f166 d109b18f 75277f79 30d55ceb 22e8adba 794c155c ed74cbdd 5fc5d36d b19b0a58 35cca7e3 |
Po pozorném prozkoumání obou řetězců zjistíte že se liší, výsledný řetězec je však v obou případech:
1 |
a4c0 d35c 95a6 3a80 5915 367d cfe6 b751 |
Celý algoritmus zřejmě závisí na inicializačním vektoru a pro výpočet na notebooku IBM P690 trval výpočet asi jednu hodinu.
V této době laboratoře RSA doporučili přejít na algoritmus SHA-1.
Nicméně je hashovací algoritmus MD5 stále hojně užíván. Sice byly nalezeny kolize, ale stále patří k velmi bezpečným řešením.
Louskání hesla
MD5 je tedy hashovací funkce, která se většinou používá pro ukládání hesel v databázi.
Pokud by jste v praxi získali takové heslo, zakódované jednou funkcí MD5, a pokud není složeno z různých alfanumerických znaků, ale pouze z malých písmen a číslic, a víte o něm, že není dlouhé, není pro vás zase takový problém jej prolomit.
Můžete použít například program Cain&Abel (programů je celá spousta) a prolomení takového hesla o délce 5 znaků je potom otázka opravdu na několik minut i pro Brute-Force Attack. Na příkladu si ukážeme slovo „heslo”jehož hash je „955db0b81ef1989b4a4dfeae8061a9a6”. Prolomení tohoto hesla trvá opravdu jenom několik málo okamžiků i na podprůměrném počítači:
Nastavili jsme testování hesel, o délce od 4 do 6 znaků. Vidíte že počet kombinací při použití znaků „abcdefghijklmnopqrstuvwxyz1234567890” je otázka 13 minut, přičemž počitač tetuje rychlostí 2 748 622 hesel za sekundu.
Takový program není aní složité naprogramovat. Stačí vytvářet řetězce o požadované délce, které budou složeny z předem zadaných znaků. Jediné co potřebujete je knihovna pro kódování MD5. Program je potom v například v jazyce C otázkou několika řádků a kvalitního algoritmu.
Bohužel u hesel delších než nějakých 8 znaků, nebo heslo složené z malých a velkých znaků abecedy by se doba pro prolomení zvýšila na několik dní až desítky nebo stovky let. To je pro nás nepřijatelné. Ale nezoufejte. Můžete vyzkoušet cracknout heslo pomocí „Dictionary attack”
Jedná se o druh útoku, při kterém využíváte určitý předem vytvořený seznam hesel. Tento seznam postupně procházíte a každé slovo zakódujte pomocí MD5.
Pro útok zase můžete použít zase program Cain&Abel, nebo si program opět vytvořit. Stačí číst ze vstupního souboru jednotlivé slova a testovat jejich hash s výsledným hashem, který se pokoušíme rozlousknout.
Podobny skript by jsme si mohli zpracovat i v PHP. Budeme mít tabulku se slovy a jejich md5 hash. Při hledání budeme prohledávat tabulku a hledat stejný hash slova.
Nejprve si tedy musíme vytvořit tabulku, ve které budou uloženy všechna slova. Dále formulář pro vkládání a hledání slov.
Celý skript může vypadat takto:
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 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 91 92 93 94 95 96 97 98 99 100 101 102 103 |
function __autoload($name) { // funkce pro includování děděné třídy require_once $name . '.php'; } //naše třída class c_md5 extends connect { public $word; public $table_name = "words"; //konstruktor function __construct($action){ parent::__construct(); self::menu(); self::stats(); $this->word = (isset($_POST['new_word']) ? $_POST['new_word'] : NULL); switch($action){ case 'create': self::new_table(); break; case 'new_word' : self::add_word(); break; case 'find_word': self::find(); break; default: return 0; } } //funkce vypíše počet slov v tabulce function stats(){ $select = "SELECT COUNT(*) from " . $this->table_name . ";"; @$data = mysql_query($select, $this->link); print 'Number of words: ' . @mysql_result($data, 0, 0) . '<br />'; } //funkce vypíše menu function menu(){ print '<a onclick="w_s('new')">Create Table</a> | <a onclick="w_s('add')">Add Word</a> | <a onclick="w_s('find')">Find Word</a><br />'; } //funkce pro vytvoření tabulky function new_table() { $sql = "CREATE TABLE " . $this->table_name . "( id_word INTEGER NOT NULL AUTO_INCREMENT, word VARCHAR(100), md5_word VARCHAR(33), PRIMARY KEY(id_word));"; if(mysql_query($sql, $this->link) == 0){ print 'Error<br />'; return 0; } return 1; } //funkce pro přidání slova function add_word(){ if($this->word == NULL) return 0; $insert = "INSERT INTO " . $this->table_name . "(word, md5_word) VALUES('" . htmlspecialchars(trim($this->word)) . "', '" . md5(htmlspecialchars(trim($this->word))) . "')"; if(mysql_query($insert, $this->link) == TRUE) print 'OK'; else print 'Error'; } //funkce pro nalezení slova function find(){ if($this->word == NULL) return 0; $select = "SELECT word FROM " . $this->table_name . " WHERE md5_word = '" . md5(htmlspecialchars(trim($this->word))) . "' LIMIT 1;"; if(mysql_num_rows($data = mysql_query($select, $this->link)) == 0) { print 'Nothing'; return 0; } print 'word: ' . $this->word . ', md5: ' . mysql_result($data, 0, 0) . '.'; } } //volání třídy if(isset($_POST['action'])) $use = new c_md5(trim($_POST['action'])); <!—funkce pro zobrazování menu –> <script> function w_s(idecko){ el=document.getElementById(idecko).style; el.display=(el.display == 'block')?'none':'block'; } </script> <!—potřebné formuláře –> <span id="add" style="display: none"> <form action="./index.php" method="POST"> word: <input type="text" maxlength="20" name="new_word"> <input type="hidden" name="action" value="new_word"> <input type="submit" name="ok" value="ADD"> </form> </span> |
V příštím článku se podíváme na MHASH_SHA1.
Ahoj, co je to ten MHASH? Máš to v nadpise článku, ale v článku samotném o tom není ani slovo 🙂 Google říká, že mhash je LGPL knihovna poskytující rozhraní k hashovacím algoritmům, ale souvislost nevidím.
Ahoj,
v nadpise neni MHASH, ale MHASH_MD5.
viz:
http://zaachi.com/cs/items/hashovaci-funkce-kodovani-dat.html
DL