Autentizace: Jak v systému bezpečně uložit heslo

O tom, jak si vytvořit bezpečné heslo, a jaká pravidla dodržovat, jsme již psali. V dnešním příspěvku se proto podíváme na to, jakým způsobem bychom měli heslo, které si uživatel vytvořil, v systému uložit.

Útočník se může k souboru nebo databázi obsahující hesla uživatelů dostat mnoha různými způsoby. V prostředí internetu jsou nejznámější případy, kdy útočník zneužil nějaké zranitelnosti webové aplikace např. SQL injection, a získal tak přístup k databázi hesel. Stejně tak může útočník získat fyzický přístup k systému a daný soubor s hesly si jednoduše zkopírovat a konečně může se jednat i o situaci, kdy společnost vyřadí již nepotřebnou výpočetní techniku a neprovede bezpečnou likvidaci dat.

V zásadě máme jen dvě možnosti, jak hesla uživatelů chránit. Můžeme je buď šifrovat, anebo ukládat jejich hash. (Předpokládám, že vás ani nenapadlo, že byste hesla ukládali v plaintextu.) V případě šifrování však někde musí být uložen klíč, kterým se hesla šifrují a dešifrují, a ten, kdo se zmocní klíče, může snadno zjistit všechna hesla, a proto tuto možnost zavrhneme a nebudeme se jí dále zabývat. V naprosté většině případů je místo šifrování vhodnější použít nějakou hashovací funkci a ukládat pouze hash daného hesla.

Využíváme skutečnosti, že hashovací funkce je jednosměrná a z hashe není možné odvodit původní heslo. Tato metoda má však jednu nevýhodu, uživatelé, kteří si zadají stejné heslo, mají i stejné hashe. Uživatel, který si zadá stejné heslo na různých systémech, má pak na různých systémech stejný hash. A konečně, pokud je použito slabé heslo, tak lze takové heslo velice rychle prolomit za pomocí předvypočtených hashů (precomputed hashes) uložených v rainbow tables.

Z těchto důvodů je vhodné k heslu, které si uživatel zadal, přidat ještě sůl (salt), a to pro každého uživatele unikátní. Tím nejenže ztížíme, ne-li znemožníme útok za použití předvypočtených hashů, ale i v případě, že si dva uživatelé zadají stejné heslo, budou v systému uloženy dva zcela odlišné hashe.  Provede se to tak, že heslo zadané uživatelem a sůl vygenerovaná systémem se spojí do jednoho řetězce a až pro ten spočte hash.

Sůl je možné vložit před heslo (prefix), za heslo (postfix) ale také třeba někam doprostřed, což může útočníkovi znesnadnit prolamování. Pokud by útočník znal kromě hashe i patřičnou sůl, musel by pro úspěšné lámání hesel ještě zjistit, jak přesně algoritmus se solí zachází. To útočník může zjistit, ale také nemusí, zaleží na tom, zda může provést analýzu kódu. Solí by měl být dostatečně náhodný řetězec znaků, o určité délce, kterou bychom měli volit podle minimální délky hesla a počtu uživatelů.

Na první pohled se může zdát, že sůl o délce 32bitů, by měla všem stačit, vždyť 2^32 představuje 4.294.967.296 jedinečných hodnot. Záleží ale na tom, jaká je minimální délka hesla a zda se útočníkovi podařilo získat přístup k databázi hesel, ve které bývají obvykle uvedeny i další informace. Běžně se uvádí, že sůl není tajná informace a tudíž není potřeba ji chránit. Pravda, útočník nemůže použít již hotové rainbow tables, neboť ty nejsou vygenerovány pro danou sůl, nic mu ale nebrání v tom provést útok hrubou silou.

Pokud by např. minimální délka hesla byla sedm znaků, stačí útočníkovi ke každé vygenerované kombinaci znaků přičíst známou sůl a poté spočítat hash. Vzhledem k tomu, že sůl je pořád stejná a je obvykle přičtena k heslu uživatele, můžeme předpokládat, že útok by trval stejně dlouho jako vyzkoušení všech kombinací pro sedmiznakové heslo. Problém nespočívá v délce soli, a dokonce ani tak v tom, že je její hodnota známa, ale v samotné délce hesla. Je prostě příliš krátké. Přesvědčit se můžete sami, když do brute force calculatoru dosadíte odpovídající hodnoty.

Vzhledem k tomu, že uživatelé mají tendenci používat slabá hesla, může být hashovací funkce aplikována na heslo několikrát. Tato technika se označuje jako „key stretching“. Ve své nejjednodušší podobě může cyklus vypadat např. nějak takto: key = hash(heslo,sůl); for 1 to X do hash = hash(key). Kde hash je algoritmus, který bude použit např. SHA1 nebo SHA2 a X je počet opakování. Systém, který tuto techniku implementuje, musí sice pro každého uživatele resp. při každém zadání hesla provést tuto výpočetně náročnou operaci, ovšem útočník, pokud by se rozhodl lámat heslo hrubou silou, by musel tuto operaci provést pro všechny možné kombinace. Navíc u každého uživatel může být použit jiný algoritmus a jiný počet cyklů.

Předpokládejme, že uživatel si jako heslo zvolil řetězec P4$$w0rd. Pokud bychom toto heslo předali jako parameter hashovací funkcí, byl by výsledkem této funkce řetězec: 0500d3ea386688a0147ab736aabcede496610382. Pokud by si stejné heslo zadal i jiný uživatel, měli bychom v systému uložené dva naprosto stejné hashe. Proto vygenerujeme 32bitovou náhodnou sůl např. x4d# a tu k heslu přičteme, výsledkem tedy bude řetězec P4$$w0rdx4d# a teprve tento řetězec předáme ke zpracování hashovací funkci. Výsledkem funkce je tento hash: 1b58660d0c40614aae483603af75ab1b2de168fe.

Pro jiného uživatele, který si též zadal heslo P4$$w0rd též vygenerujeme náhodnou sůl např. 12?r. Sůl opět přičteme k heslu a získáme tento řetězec: P4$$w0rd12?r a pro ten spočteme hash, kterým je v tomto případě tento řetězec: 0dc27957b82e784c730ed63f94ecceb3558a9d35. Vidíme, že byť si oba uživatelé zadali naprosto stejné heslo, jsou v system uloženy dva naprosto rozdílné hashe.

Poznámka: V DB budou pro každého uživatele existovat tyto záznamy: username, použitá hashovací funkce, počet cyklů, vlastní hash a samotná sůl.

Při autentizaci uživatel zadá své jméno a heslo. Systém si vyhledá, jaká sůl byla použita, k heslu ji přičte, spočte hash a výsledek porovná. Pokud se vypočtený hash bude shodovat s hashem uloženým v systemu, uživatel zadal heslo správně, v opačném případě bylo heslo zadáno chybně. Systém by měl po uživateli požadovat zadání silného hesla, dále by měla být použita kvalitní hashovací funkce, vygenerována dostatečně dlouhá a náhodná sůl a použita technika key stretching.


Pokud vás tento příspěvek zaujal, sdílejte ho!
Share on FacebookShare on LinkedInTweet about this on TwitterShare on Google+Email this to someonePrint this page

Štítky:


K článku “Autentizace: Jak v systému bezpečně uložit heslo” se zde nenachází žádný komentář - buďte první.

Diskuse na tomto webu je moderována. Pod článkem budou zobrazovány jen takové komentáře, které nebudou sloužit k propagaci konkrétní firmy, produktu nebo služby. V případě, že chcete, aby z těchto stránek vedl odkaz na váš web, kontaktujte nás, známe efektivnější způsoby propagace.

Přihlášeným uživatelům se tento formulář nezobrazuje - zaregistrujte se.

Jméno:(požadováno)
E-mail:(požadováno - nebude zobrazen)
Web:

Text vaší reakce: