Autentizace: Jak po síti bezpečně přenést heslo

Heslo bychom nikdy neměli po síti přenášet v otevřeném tvaru, protože v takovém případě může být snadno odchyceno.

První, co každého asi napadne, je komunikovat se serverem přes HTTPS, kdy uživatel zadá do webového formuláře své jméno a heslo, a po kliknutí na tlačítko odeslat, se tyto údaje přenesou bezpečným kanálem na server. Zde se k heslu přičte sůl a pro vzniklý řetězec se spočte hash, který se uloží do DB. Při autentizaci se pak postupuje stejným způsobem. Uživatel zadá heslo, to se přenese na server, kde se k němu přičte sůl, a spočte se hash, který se porovná s hashem uloženým v DB. Pokud se oba hashe rovnají, bylo heslo zadáno správně a uživatel může být přihlášen.

HTTPS resp. SSL/TLS snižuje riziko, že heslo přenášené v otevřeném tvaru bude odchyceno při přenosu a ukládání osolených hashů (salted hash) v DB zase snižuje riziko v případě nabourání do DB.

Tento nejjednodušší způsob autentizace, kdy je heslo a uživatelské jméno spojeno do jednoho řetězce zakódovaného metodou Base64 a následně přenášeno přes SSL v de facto otevřeném tvaru, však nelze považovat za bezpečnou metodu autentizace, což je ostatně uvedeno i v RFC 2617, kde je popsána HTTP autentizace. Nezapomínejte, že pokud není SSL sestaveno od začátku do konce, což v případě vícevrstvé HW architektury nemusí být vždy zajištěno, putují potom hesla mezi servery v otevřeném tvaru. I kdybychom hash generovali přímo na klientovi, tak si nepomůžeme, protože útočník může odchytit hash stejně dobře jako heslo přenášené v otevřeném tvaru a též ho použít pro přihlášení.

Rozhodneme-li se pro challenge-response autentizaci, kde je při každé autentizaci vygenerována nová výzva, tak i v případě, že by se útočníkovi podařilo zachytit výzvu a odpověď, nemůže ji zneužít.

Dobře, do DB tedy uložíme hash hesla. Server vygeneruje náhodný řetězec (nonce), který zašle klientovi jako výzvu (challenge). Klient zadá své heslo (password) a spočte pro něj hash H(password). Ke spočtenému hashi přičte nonce a pro vzniklý řetězec spočte hash H(H(password),nonce). Tento hash zašle na server jako odpověď (response). Server má ve své DB uložen hash hesla a zná i výzvu, kterou klientovi poslal, takže může snadno spočítat hash stejným způsobem jako klient a oba hashe porovnat.

Tímto způsobem jsme snížili riziko odchycení hesla při přenosu, neboť ze zachycené výzvy ani odpovědi není útočník schopen heslo zjistit, ovšem v DB jsou nyní uložené neosolené hashe.

Neosolené hashe by útočník mohl snadno lámat, proto na to musíme jinak. Necháme server vygenerovat náhodný řetězec znaků (salt) a ten pošleme uživateli. Uživatel zadá své jméno a heslo a klikne na tlačítko odeslat. Na klientovi se k heslu uživatele přičte i salt a pro vzniklý řetězec se spočte hash H(heslo,salt), který se spolu s uživatelským jménem pošle na server. Na serveru se do DB uloží uživatelské jméno, hash a salt a vytvoří se uživatelský účet.

Při autentizaci se pak uživateli pošle náhodný řetězec znaků (nonce) jako tzv. výzva (challenge) a sůl (salt). Uživatel zadá heslo a spočte hash pro zadané heslo a zaslanou sůl. Ke vzniklému hashi pak ještě přičte nonce a pro tento řetězec pak opět spočte hash. Celá operace by se dala zapsat takto: H(H(heslo,salt),nonce). Výsledný hash se pošle na server jako odpověď (response).

Server zná hodnotu H(heslo,salt) tu má již uloženou ve své DB a zná i nonce, kterou klientovi poslal, takže může hash spočítat stejným způsobem jako klient: H(H(heslo,salt),nonce). Oba hashe, tedy ten, který obdržel od klienta a ten který si sám spočítal, porovná. Pokud se hashe shodují, uživatel zadal správné heslo a může být přihlášen do systému, v opačném případě bylo heslo zadáno špatně a požadavek na přístup do systému je zamítnut.

Nevýhoda výše uvedeného řešení je v tom, že v DB bude uložen osolený hash a sůl, k jehož změně dojde jen v případě, že si uživatel změní heslo. Pokud si uživatel heslo moc často nemění, např. proto že k tomu není nucen žádnou politikou ani systémem, má útočník dost času na to, aby se pokusil heslo prolomit. Co kdybychom do DB neukládali osolený hash, ale pouze poslední response?

Celé by to mohlo fungovat nějak takto. Při zakládání účtu by se klientovi zaslal nonce a klient by provedl H(password,nonce). Tato hodnota se pak uloží spolu s nonce do DB. Při autentizaci pak server zasílá klientovi výzvu (challenge), který obsahuje naposledy použitou nonce (nonce_old), který je uložen v DB, a nově vygenerovanou nonce (nonce_new). Klient zadá heslo (password), to se spojí s nonce_old a spočte se hash, který se vzápětí spojí s nonce_new a pro vzniklý řetězec se spočte výsledný hash (H1). Dále klient spočte hash (H2) pro password a nonce_new. Oba hashe klient pošle serveru jako odpověď (response).

Vzhledem k tomu, že server má hash H(password,nonce_old) uložen ve své DB, není pro něj problém též spočítat H1(H(password,nonce_old),nonce_new) a porovnat, zda výsledný hash souhlasí s hashem, který obdržel od klienta. Pokud ano, přepíše ve své DB hash a nonce aktuálními hodnotami tj. do sloupce hash se uloží hodnota H2 a do sloupce nonce se uloží nonce_new. Výhodou této metody je, že v DB je uložena hodnota, která je hashem hesla a náhodně vygenerovaného řetězce, a která se s každým přihlášením uživatele mění.

Poznámka: Nonce může kromě náhodného řetězce znaků obsahovat i timestamp, tedy čas generovaný na serveru. H je libovolná hashovací funkce, můžeme použít i HMAC.

Závěr: Uvedená metoda autentizace není samozřejmě sama o sobě zcela bezpečná, ovšem v případě použití protokolu SSL, lze hovořit o poměrně bezpečném řešení. Vlastní implementace tohoto autentizačního mechanismu by též neměla být problém, neboť na SourceForge je k dispozici JavaScript, který podporuje celou rodinu SHA, tak jak je definována ve FIPS 180-2 včetně HMAC.

Pro citování tohoto článku ve své vlastní práci můžete použít následující odkaz:
ČERMÁK, Miroslav, 2011. Autentizace: Jak po síti bezpečně přenést heslo. Online. Clever and Smart. ISSN 2694-9830. Dostupné z: https://www.cleverandsmart.cz/autentizace-jak-po-siti-bezpecne-prenest-heslo/. [citováno 07.12.2024].

Pokud vás tento článek zaujal, můžete odkaz na něj sdílet.

Štítky:


K článku “Autentizace: Jak po síti bezpečně přenést 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: