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:
-
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í)
-
Opakované hashování stejného vstupu, stejným
algoritmem se stejnými parametry vede vždy ke stejnému výstupu
-
Hashování stejným algoritmem vytváří výstup o
konstantní délce, bez ohledu na množství vstupních dat.
-
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.