Blog - Kodrla.eu

Heč, už vím, co je heš!

A jestli to chcete vědět i vy, přečtěte si dnešní článek.

Na úvod se omlouvám za ten čechismus a od této chvíle budu už používat jen výraz hash. V tomto článku si vysvětlíme, co je hash a hashování, k čemu slouží a kdy a jaké použít. Pro běžné použití nepotřebujeme jít do hloubky algoritmů, proto věřím, že na konci článku už i vy budete vědět, co je hash.

Hashování je kryptografická operace, při které se vstupní data převádějí na data výstupní. Pro hashování se používají hashovací algoritmy, matematické postupy, které provádějí definované operace. Výstupní data, tzv. hash (otisk nebo fingerprint) bývají obvykle zobrazována jako dlouhý řetězec alfanumerických znaků, aby byl snadno čitelný i pro lidi. Hash je definován těmito vlastnostmi:

  1. Hashování je jednosměrné, tj. je nemožné matematickými operacemi z výstupních dat vytvořit data vstupní (což je rozdíl proti šifrování)
  2. Opakované hashování stejného vstupu, stejným algoritmem se stejnými parametry vede vždy ke stejnému výstupu
  3. Hashování stejným algoritmem vytváří výstup o konstantní délce, bez ohledu na množství vstupních dat.
  4. Sebemenší změna vstupních dat vede ke zcela odlišnému výstupu. Této vlastnosti se říká avalanche efekt – i změna jediného bitu způsobí dramatickou změnu celého hashe. (A protože chci psát o praxi, klidně přiznám, že jsem termín avalanche efekt nikdy nevyslovil.)

Ověřování integrity počítáním hashe

Pojďme si hashování a porovnání výstupů ukázat trochu prakticky. Když budeme hash počítat opakovaně, dostaneme vždy stejný hash. A to jak na Windows, na linuxu, na Macu, ve webovém prohlížeči, kdykoli a kdekoli. Schválně si zkuste spočítat SHA-256 řetězce „Ema má mísu“ (bez uvozovek), také jste dostali tento řetězec? Můžete si na internetu najít libovolnou aplikaci pro hashování online, já jsem použil svou.

6b7ed1a5765ce419f85804f13e65ef29ff001148ec4a6f5c553715ee14a388c2

Ovšem hash řetězce „Ema má mísu “ (s mezerou za mísou) bude zcela jiný.

4a0177462a9dba0b8213d0e97b900c961ed2abedf46c7e19f3a39f3464c3633b

A hash řetězce „Ema má mísu“, kde místo mezer je nezalomitelná mezera (ALT+0160) je zase zcela jiný.

9e5e9260cbaf8a63263fb32dc22eec8e95bb0393a6e34a7e1317037fa2629934

 

Poznámka: Při kopírování textu vám prohlížeč nezalomitelné mezery převede na normální mezery, nezapomeňte je tedy přepsat zpět. Nezalomitelná mezera se píše kombinací klávesy ALT a vypsáním 0160.

Vidíme, že jedna drobná změna způsobí, že se oba hashe budou lišit do té míry, že nám stačí pohled na prvních pár znaků a na pár znaků posledních a víme, že je hash jiný. 

V kryptografii se při ověřování shody dvou hashů vždy porovnává celý hash, dokud nenalezneme rozdíl. V běžné praxi ale často stačí podívat se na několik prvních a posledních znaků.

Obdobným způsobem můžeme ověřit integritu i souborů, jen se místo textu použije proud dat. Pokud hash souboru souhlasí s hashem, který zveřejnil a potvrdil výrobce, víme, že jde o ten samý soubor, ať už je jeho zdroj stažení jakýkoli. Může být stažený přímo z webu výrobce, může být ze softwarového katalogu, je to jedno. Hash souhlasí, je to originál. Hash nesouhlasí, musíme zbystřit a zjistit, zda jde o jinou verzi (a opět ověřit hash), nebo o podvrh.

U souborů se ještě na chvilku zastavíme. Říkali jsme si, že sebemenší změna znamená i změnu hashe. Zde je důležitá výjimka (i když logická): změna jména souboru nebo atributů souboru (H, S, A…) neznamená změnu hashe. Co se naopak počítá, to jsou třeba EXIF informace u fotky, ID3 tagy u MP3 souboru nebo informace o dokumentu u DOCX souboru, protože jde o informace uložené uvnitř souboru. To je velice důležité pro bezpečné určování integrity podle hashe. Hash se počítá z datových proudů v souboru, proto se název souboru do výpočty hashe nezahrnuje.

Pro spočítání hashe souboru na Windows konečně po dlouhých letech nemusíme použít externí nástroje, protože PowerShell má cmdlet Get-Filehash. Na jednoduchý způsob pro řetězce snad také jednou dojde.

Nejběžnější hashovací algoritmy

Nejběžnějším hashovacím algoritmem současnosti je SHA-2, zejm. SHA-256 a SHA-512. Proč se SHA-2 rozděluje? Ve skutečnosti jde o celou rodinu algoritmů s různou délkou výstupu. Číslovka za SHA označuje délku hashe v bitech. Delší hash poskytuje vyšší odolnost vůči kolizím, zatímco kratší varianty bývají praktičtější a úspornější. SHA-256 aktuálně představuje dobrý kompromis mezi bezpečností a použitelností, proto se z něj stala de facto univerzální volba. Poskytuje vysokou rychlost, jeho výstup je relativně krátký, ale je pořád dostatečně bezpečný.

V minulosti se pochopitelně používaly i mnohé další algoritmy. Dodnes můžete slyšet zejm. starší ajťáky mluvit o „em dé pětce“. Algoritmus MD5 byl jedním z prvních masově rozšířených hashovacích algoritmů a na dlouhá léta se stal téměř synonymem pro hash. Nicméně dnes už je považovaný za nedostatečný, podobně jako SHA-1, který byl po mnoho let standardem například v certifikátech a digitálních podpisech. SHA-1 je dnes na ústupu a spíše jen dožívá ve stávajících implementacích.

Co je příčinou ústupu od starších algoritmů? Nejvážnějším důvodem, proč se algoritmy opouštějí, je vytvoření kolize. Kolize znamená, že dva různé vstupy vytvoří stejný hash, což je u kryptografického hashování zásadní problém. Pokud lze kolize cíleně vytvářet, útočník může například vytvořit dokument, který má stejný hash jako dokument jiný, nebo obejít některé mechanismy ověřování integrity. Algoritmus pak už nelze považovat za dostatečně bezpečný pro moderní kryptografické použití.

Vzhledem k matematické nevyhnutelnosti kolizí není problémem jejich samotná existence, ale možnost je cíleně vytvořit.

 Použití

Jak už jsme si řekli, hashování je jednosměrné. Ze zdroje odvodím výstup, ale z výstupu zdroj neodvodím. Proto se hashování používá tam, kde potřebuji zachovat důvěrnost informace, ale nepotřebuji znát samotnou informaci. Protože si pod tím asi nikdo nic nepředstaví a mým cílem je psát o praktických věcech, dáme si konkrétní příklad – přihlášení do webové aplikace.

Do databáze ukládáme pouze hash hesla. Když se uživatel přihlásí, aplikace spočítá z jeho hesla hash a porovná jej s hashem uloženým v databázi. Pokud hashe souhlasí, spolehneme se na druhé pravidlo – stejný vstup dává stejný výstup - a můžeme říct, že bylo zadané správné heslo. (Ve skutečnosti je proces autentizace složitější, a pokud vás zajímá, podívejte se na článek [doplním odkaz].)

Dalším – a mnohem typičtějším – použitím hashování je kontrola integrity. Řekli jsme si, že sebemenší změna vstupu způsobí změnu výstupu. S úspěchem toho můžeme využít ve chvíli, kdy potřebujeme garantovat, že se např. soubor nebo text nezměnil. Jestliže při vytvoření informace (textu, souboru) spočítáme její hash, kdykoli později můžeme v pochybnostech provést výpočet znovu a ověřit si, jestli hash souhlasí. Hash nám nezaručí integritu dat, nebrání tomu, aby byla pozměněna, a neřekne nám, kde nebo jak byla změněna. Ale zaručí nám, že změnu dokážeme spolehlivě detekovat.

Když rychlost škodí

Už jsme si řekli, že jednou z vlastností hashovacích algoritmů je jejich rychlost. V některých případech je však vysoká rychlost hashování spíše nevýhodou, typicky při ukládání hashů hesel pro autentizaci. Pokud útočník získá databázi hashů hesel, může zkoušet obrovské množství vstupů metodou brute force nebo slovníkovým útokem.

Poznámka: databáze hesel se běžně prodávají na Darknetu, takže to „Pokud útočník získá“ není jen teoretická úvaha.

Rychlé algoritmy, jako SHA-256, umožňují testovat extrémní množství kombinací během krátké doby, zejména při použití moderních GPU. Proto se pro ukládání hesel používají specializované "pomalé" algoritmy, jako Argon2, bcrypt nebo scrypt. Ty záměrně zpomalují výpočet, například pomocí iterací a vyšších nároků na paměť, takže ověření hesla trvá déle, řádově ve stovkách milisekund. Uživatel si takového zpoždění vůbec nevšimne, ale útočníkovi výrazně prodlužuje čas potřebný k prolomení hesel. (Ve skutečnosti se neukládají prosté hashe, ale přidává se tzv. kryptografická sůl. Ale o bezpečném ukládání přihlašovacích údajů do databáze si povíme zase někdy jindy.)

Rozdíl v rychlosti je dramatický. Moderní grafické karty dokážou u rychlých hashovacích funkcí počítat miliardy hashů za sekundu. Naproti tomu pomalé algoritmy bývají záměrně nastavené tak, aby jedno ověření hesla trvalo výrazně déle. Místo miliard pokusů za sekundu tak útočník zvládne za stejný čas jen desetitisíce, v lepších případech i tisíce, pokusů.

 Kontrolu integrity nám zajišťuje například elektronický podpis, ale na ten se podíváme až někdy jindy.