Autentizace jménem a heslem
Autentizace jménem a heslem patří mezi nejrozšířenější způsoby autentizace. V tomto článku si ukážeme, na co si dát pozor, pokud se rozhodneme tento způsob autentizace implementovat. Nejprve si ale připomeneme, co znamenají pojmy autentizace a autorizace.
Autentizace a autorizace
Subjektem nazveme kohokoliv, kdo komunikuje s naší aplikací. Typicky se jedná o uživatele, nicméně subjektem může být také další systém či aplikace.
Autentizace je proces ověření identity subjektu. V případě autentizace jménem a heslem se tedy jedná o ověření, že zadané jméno a heslo je správné a subjekt je skutečně tím, kým tvrdí, že je.
Autorizaci lze chápat jako proces ověření oprávnění. Subjektu, který nemá potřebná oprávnění, není umožněno danou akci provést. Aby subjekt potřebná oprávnění získal, musí se nejprve autentizovat.
Příkladů na autentizaci a autorizaci existuje celá řada. Uveďme jeden příklad ze života.
Mladíci Petr a Pavel šli do hospody na pivo. Při objednávání chtěl číšník vidět jejich občanky. Petr občanku neměl (neautentizoval se), a proto pivo nedostal (nebyl autorizován k pití piva). Pavel občanku ukázal (autentizoval se) a pivo dostal.
Sami dokážete jistě vymyslet mnoho dalších příkladů.
Uložení hesla
Alfou a omegou autentizace jménem a heslem je problém uložení hesla. Naše aplikace potřebuje umět rozhodnout, zda je zadané heslo daného uživatele správné.
Nejjednodušším řešením, které nás napadne, je do databáze uložit spolu s uživatelským jménem i heslo. Takové řešení je však velmi nebezpečné, protože každý, kdo získá přístup do databáze, získá zároveň hesla všech uživatelů.
Lepším řešením je uložit do databáze místo hesla pouze jeho hash. K výpočtu hashe použijeme některou ze standardních hashovacích funkcí např. SHA-256.
Hashovací funkce jsou jednosměrné, což v praxi znamená, že neexistuje žádný efektivní algoritmus, který by dokázal z hodnoty hashe vypočítat původní vstupní hodnotu.
Laici občas zaměňují pojmy hashování a šifrování (resp. kryptování). Někdy říkají, že hesla kryptují, ačkoliv je hashují. Jedná se však o zcela rozdílné algoritmy. Hashovací funkce dostane vstup a vrátí výstup fixní délky. Šifrovací funkce pro daný klíč a vstup (otevřený text) vrátí výstup (šifrový text). Z šifrového textu lze díky znalosti klíče získat zpět otevřený text.
V případě, že do databáze uložíme místo hesla pouze jeho hash, probíhá následné ověření takto:
- Uživatel zadá uživatelské jméno a heslo a odešle ho naší aplikaci.
- V databázi se pro zadané uživatelské jméno vyhledá příslušný záznam.
- Pokud žádný záznam neexistuje, autentizace selže.
- Vypočítá se hash zadaného hesla
- Porovná se vypočítaný hash s hashem v databázi. Pokud se hodnoty shodují, uživatel je úspěšně autentizován. V opačném případě autentizace selže.
Toto řešení má ale stále několik nedostatků:
- Z databáze lze snadno poznat, kteří uživatelé mají stejná hesla.
- Existují předem vypočítané převodní tabulky z hashe na původní vstup. Schválně zkuste např. do Google zadat B37DD682B63E2654CDBB67E6EADE9A2346EB12CD. Už víte jaké je moje heslo, když vám řeknu, že toto je jeho hash?
- Velikost převodních tabulek lze redukovat pomocí techniky Rainbow tables.
Tyto nedostatky lze eliminovat pomocí tzv. soli (anglicky salt).
Sůl
Sůl je náhodný řetězec, který se vygeneruje vždy při vytvoření nového hesla nebo při jeho změně. Hash se následně vypočítá z hodnoty sůl || heslo. Pokud mají dva uživatelé stejné heslo, příslušné hodnoty hashe se liší, protože se liší hodnoty solí. Najít hodnotu vstupu pro daný hash je obtížnější, neboť délka vstupu je díky soli větší.
Podívejme se, jak nyní probíhá ověření hesla:
- Uživatel zadá uživatelské jméno a heslo a odešle ho aplikaci.
- V databázi se pro zadané uživatelské jméno vyhledá příslušný záznam.
- Pokud žádný záznam neexistuje, autentizace selže.
- Z načteného záznamu se získá hodnota soli a hodnota hashe.
- Ze soli a zadaného hesla se vypočítá hash.
- Vypočítaný hash se porovná s hashem v databázi. Pokud se hodnoty shodují, uživatel je úspěšně autentizován. V opačném případě autentizace selže.
V případě SQL databáze, můžeme sůl buď uložit do samostatného sloupce, nebo do sloupce jednoho spolu s hashem.
Jakou velikost soli zvolit? Dostatečnou velikostí se zdá být 16 bytů, kterou používá algoritmus crypt na Unixu. Organizace OWASP doporučuje velikosti 4 nebo 8 bytů. Standard PKCS #5 uvádí doporučenou délku soli 8 bytů, ale tato sůl se používá k odvozování klíčů z hesel, což je jiný případ použití soli.
Neplatné jméno nebo heslo
Existují dva základní důvody k selhání autentizace jménem a heslem.
- Uživatelské jméno je neplatné
- Uživatelské jméno je platné, ale heslo je neplatné
I když naše aplikace dokáže tyto stavy odlišit, z bezpečnostních důvodů se obvykle tyto informace uživatelům nesdělují. Pokud bychom tyto informace poskytovali, dáváme potenciálnímu útočníkovi k dispozici rozhraní, které mu umožní zjistit, zda existuje uživatel se zadaným jménem či nikoliv.
Bezpečná aplikace by měla poskytovat přesně tolik informací, kolik je potřeba pro uživatelův komfort, ale nic víc.
Zapomenuté heslo
Lidé zapomínají. Aplikace by proto měla nabízet nějaký způsob, jakým lze vytvořit heslo nové.
Nové heslo pokud možno neposíláme e-mailem. Místo toho raději pošleme adresu stránky, na které si uživatel může nové heslo zadat. Adresa by měla mít omezenou dobu platnosti.
Kvalita hesla
Pokud v aplikaci zavedeme pravidla, která donutí uživatele volit silnější hesla, můžeme tím docílit vyšší bezpečnosti. Určitě je vhodné definovat minimální délku hesla.
Druhou stranou mince takových pravidel ale je, že tím uživatele omezujeme a snižujeme přívětivost naší aplikace. Vždy je třeba zvážit, jaká pravidla jsou pro konkrétní aplikaci vhodná. Ne každého uživatele potěší, pokud si musí každý měsíc měnit heslo.
Webový formulář
U webových aplikací používáme k přenosu hesel HTTP metodu POST, mimo jiné také proto abychom zabránili zobrazení hesla v URL prohlížeče.
Některé webové prohlížeče nabízejí uživatelům možnost zapamatování hesla v prohlížeči. To sice může být v některých případech užitečné, nicméně z bezpečnostních důvodů můžeme chtít tuto funkci zakázat. Toho docílíme nastavením atributu autocomplete na hodnotu off. Atribut lze buď nastavit pro celý formulář nebo na jednotlivých elementech INPUT.
Závěr
Hashování a solení hesel jsou základními techniky používaných při ukládání hesel. V článku jsme si vysvětlili, proč je dobré tyto techniky používat a jaké výhody to přináší.