Tech Life

Ilustrační obrázek

Někdo to rád slané

24. 03. 2009 13:15    kategorie: Tech Life    autor: RSl    komentářů: 10

Určitě máte ve svých archivech aplikaci, která ukládá hesla uživatelů rovnou do databáze. Určitě jste časem zjistili, že to není nejlepší způsob a řešili jste, jak to zamaskovat. Určitě jste využili nějaké hashovací algoritmy a asi jste žili v domnění, že to máte už dostatečně zabezpečené. Ale je tomu tak doopravdy? Pokud jste to posolili, tak je pravděpodobné, že ano...
 

Mějme následující data v databázi:

LOGIN PWD_HASH
dulezity_klient qUqP5cyxm6YcTAhz05Hph5gvu9M=
test qUqP5cyxm6YcTAhz05Hph5gvu9M=

Kvízová otázka zní: jaké je heslo uživatele dulezity_klient?

Že už víte? Ale to byste správně něměli, co?

Hesla jsou přeci zahashovaná bezpečnou hashovací funkcí SHA-1 a všude píšou, že jak se použije ten hash, je to rázem bezpečné; považte, sami to nedokázali prolomit a že se snažili.

Pokud jste neuhodli heslo na první pohled, zkuste ten “bezpečný” hash vygooglovat.

Něco zřejmě není v pořádku:

  • pro utajení hesla není moc přínosem, pokud se stejné heslo zakóduje vždy stejně. Dá se podle něj sice hledat v databázi, ale také se podle něj dá v databázi i najít - např. kdo všechno má stejné heslo a to občas i mimo naši aplikaci, pokud je algoritmus shodný včetně parametrů.
  • pro utajení hesla není dobré ani to, pokud existují (nebo dokonce jsou veřejně přístupné) tabulky s inverzním mapováním - stačí i pokud jsou jen pro častá slova.

Vysvětlíme si, kde se stala ona chyba.

Špatný postup

Toto je zdrojový kód aplikace, který generuje výše zmíněná hesla:

Ponechme stranou drobné stylistické nedostatky (jako např. zbytečné kopírování pole, zbytečné base64 kódování když máme VARCHAR BINARY / setBytes).

Hlavní problém tkví v tom, že hashovací funkce je:

  • veřejně známá (je to prostá SHA-1 bez klíče, každý ví, co je bgF7VGT4IKbBu16fbXEaZnqA2Oo=).
  • deterministická (když uhodnu jedno heslo, uhodl jsem všechny jeho výskyty).

Oba problémy se dají vyřešit přidáním malého množství náhodné informace - tzv. salting. Pak se nedá předvídat, jaký bude výsledek hashování a tedy nejde zkonstruovat předem vypočítaná reverzní funkce (resp. časová a prostorová náročnost takového výpočtu stoupne natolik, že už není prakticky proveditelný).

Jak by to tedy mohlo vypadat správně?

Správný postup

Vytvoření hashe

Ověření hesla

Na rozdíl od předchozí implementace nelze podle hashe hledat v databázi. Musí se tedy napřed vybrat záznam podle loginu a pak provést ověření.

Sdílet odkaz:
tisk

Diskuze k článku

Anonym, 7.4.2009 21:49

2 Ales Jary : dakujeme ze kvalitny prispevok :D

RSl, 27.3.2009 13:58

Opravdu musím přiznat, že jsem se ocitl argumentačně zcela v koncích...

Aleš Jarý, 27.3.2009 13:08

Aha! Pan autor neumí argumentovat a tak vtipně odkazuje na Amazon. "Objednej a přečti" je něco jako "až naprší a uschne". To je řekl bych symptomatické pro podobné amatéry.

RSl, 27.3.2009 11:38

Článek se od začátku zabývá pouze problematikou ukládání hesel v databázi uživatelů. O bezpečnosti hesel samotných opravdu není, jakkoli se můžete snažit to tam vidět. Pokud vás problematika zabezpečení zajímá, doporučuji začít např. zde:
http://www.amazon.com/exec/obidos/ASIN/0471223573/counterpane (Practical Cryptography - Bruce Schneier a Niels Fergusson). Nebo např. kniha "handbook of applied cryptography" je volně ke stažení.

Jakub Vrána, 27.3.2009 10:16

Po takovémto zmírnění už to je přijatelné, ale článek skutečně vyzněl jako "Přidejte salt a hesla jsou bezpečná", což bohužel neplatí. Proto jsem doplnil požadavek na složitá hesla, vhodné by bylo samozřejmě také kontrolovat počet pokusů o přihlášení. Rozdělení saltu neslouží k zajištění bezpečnosti (ta je zajištěna samotným přidáním saltu a požadavkem na složitá hesla), ale toliko ke zvýšení nároků na útočníka. Proto nejde o security-by-obscurity.

RSl, 26.3.2009 18:03

O tom, že "složitější" hesla jsou bezpečnější, není sporu. Psali o tom i jiní, dlouho přede mnou a lépe než bych to dokázal já. Je možné se dočíst i o tom, že passphrase je lepší než heslo (přesto se na webu téměř nikde nepoužívá). Stejně tak praxe ukazuje, že odhodlaný uživatel si stejně najde způsob, jak mít heslo svojí silou ekvivalentní slovu "heslo123".

Možná jsem nezvolil šťastná slova; opravdu se nesnažím zcela zabránit jakýmkoli slovníkovým útokům ani vyvolávat dojem, že se mi to povedlo, protože to NEJDE (vždycky je možné zkoušet online útok - zkoušet se přihlašovat přímo do běžící aplikace). Přesnější termín by byl spíše "make pre-computed dictionary attack infeasible". Prostě pouze se snažím ze špatné implementace existujících aplikací udělat implementaci o něco lepší - nic víc.

Vámi popsaný postup "rozdělení saltu" mi připadá konceptuálně jako security-by-obscurity. Neberte to prosím jako útok; je možné, že jsem to z Vašeho popisu nesprávně pochopil. Nicméně není mi známo, že by tato technika byla nějak obecně známa nebo používána v nějaké relevantní aplikaci.

Jakub Vrána, 26.3.2009 16:59

Hlavní problém je ten, že osolení hashe a uložení soli vedle hashe slovníkovým útokům v žádném případě nezabrání. Článek i komentář se snaží vyvolat dojem, že zabrání. Rozložení saltu na více částí uložených na různých místech vyžaduje od útočníka, aby měl přístup ke všem těmto místům. Pokud ho nemá, tak se bezpečnost zvýší, pokud má, tak zůstane stejná. Proto i v tomto případě trvá podmínka chtít po uživatelích složitá hesla.

RSl, 26.3.2009 15:12

1. Salt sice může být oddělený, ale vždy se mění spolu s hashem a vždy potřebujeme pracovat s oběma údaji současně, takže oddělení nemá přílišný praktický význam. Stejně tak byste mohl požadovat, aby byl salt explicitně oddělený v /etc/shadow.
2. HMAC by jistě fungoval, nicméně program se nesnaží ani kontrolovat datovou integritu hesla coby zprávy přenesené nedůvěryhodným kanálem, ani klíč k jednosměrné funkci není nijak zvlášť tajný. Kolize hashe a podobné útoky, proti kterým chrání HMAC, jsou zde irelevantní, takže v současné podobě to svoji funkci plní.
3. Spoléhání se na to, že konstanta v aplikaci je "tajná", je možná poněkud optimistické. Mimoto zde nejde o to zabránit tomu, aby útočník heslo uhodl, jde jen o zamezení slovníkovým útokům.

Obecně lze říci, že používání hesel k autentizaci uživatelů je problematické samo o sobě, ale to už je opravdu nad rámec toho, co tento článek chtěl sdělit.

Jakub Vrána, 26.3.2009 11:41

Na kódu se mi nelíbí tři věci:

1. Salt je smíchaný v jednom řetězci s hashem, i když to jsou dvě různé hodnoty.

2. Pro osolení existuje algoritmus HMAC, kód by ho tedy měl používat.

3. To, že je salt uložen na stejném místě jako hash, znamená, že se může útočník pokusit vypočítat heslo vlastními silami (bez předpočítaných tabulek). U jednoduchých hesel to je bez problémů - viz http://php.vrana.cz/slozitost-hesel.php

Kód tedy řeší ukládání hesel jen z poloviny - nepoznám sice stejná hesla a nemůžu použít předpočítané tabulky, ale pořád si můžu heslo dopočítat sám. Ta chybějící polovina je uložit si část saltu na nějaké nezávislé místo (pokud jsou hesla v databázi, tak část saltu může být třeba jako konstanta v aplikaci) a chtít po uživatelích zadání složitějších hesel.

Adam, 25.3.2009 11:09

Díky za zajímavý článek. Škoda, že z nadpisu vůbec není poznat, o čem je - málem jsem o něj kvůli tomu přišel.

Přidat příspěvek

 

Kontakt pro média


Máte zájem o další informace, odborný článek či přednášku na konferenci? Kontaktujte nás prosím na pr@etnetera.cz.

RSS - Tech life


RSS kanál Tech Life Blogu

Offlineblog

Offlineblog

Ljama


Komix z prostředí imaginární firmy.

ljama

Ještě jste ho nečetli? Tak tudy ...

 
Doporučujeme: Nabídka práce, volná pracovní místa - pracovní portál SPRÁVNÝKROK.CZ