V souvislosti s aktuální situací jedné populární české služby se opět vyrojila nesmyslná diskuse na téma ukládání hesel v plaintextu. V tomto článku bych chtěl sdělit můj názor na věc a také prodiskutovat některé nabízené varianty.
Co je to heslo?
Ještě než začneme, pojďme si nadefinovat základní pojem, kolem kterého se to celé točí, tedy heslo.
Heslo je dostatečně dlouhý řetězec dostatečně náhodných znaků. Dostatečné aktuálně znamená 112b entropie, tedy asi 24 znaků dlouhé. Toto je nutné k tomu, aby se současnou technikou nebylo možné je prolomit v dosažitelném čase pomocí brute force.
Heslo je pro každou službu unikátní.
Autentizace
Abychom se mohli přihlásit k nějaké službě pomocí hesla (slibuji, že vás v tomto článku nebudu opět otravovat mnohem lepším způsobem pomocí asymetrické kryptografie ;-) ) musíme mít možnost, jak na straně serveru ono heslo ověřit. V konečném důsledku musíme porovnat dvě hodnoty. Hodnotu získanou od klienta a hodnotu uloženou na serveru.
A zde přichází onen střet názorů.
Ona hodnota uložená na serveru může být buď heslo v otevřeném tvaru (plain), nebo hashované heslo (hash).
Pokud máme heslo v otevřeném tvaru, klient musí poslat heslo v otevřeném tvaru. Server jej jednoduše porovná. Pokud máme heslo v hash, klient musí poslat heslo zahašované. Opět stačí jen porovnat. Obě možnosti jsou úplně stejné. Klient něco pošle, server něco porovná. Žádná výhoda ani pro jednu stranu.
Existují další možnosti hash (jako solení, digesty, scram). Výsledek je ale +- autobus pořád tentýž. Klient něco musí poslat, to něco se musí porovnat. Na rozdíl od metody, kterou preferuji a kterou jsem slíbil zde neuvádět. Vyšší metody hašování potom řeší i detekci a bránění se odposlechnutí komunikace, což je ale pro tento případ celkem bezpředmětné, protože veškerá komunikace běží po TLS kde už je toto řešeno.
Obavy odpůrců plain hesel
Po každém podobném případu, kdy se někdo dostane do interních systémů a (mimo jiné) získá i databázi s hesly, jistá skupina lidí začne křičet jaký je to amatérismus, jak si musí měnit hesla apod. Ano, uznávám, je to amatérismus. Ale na druhé straně.
Proč? Jak jsem psal před několika odstavci, heslo je pro každou službu unikátní. Pokud není, a pokud někdo používá jedno heslo pro X služeb, vůbec žádná metoda ukládání hesel v hash ho nezachrání. Důvod je jednoduchý. Stačí, aby jedna služba z oněch X nebyla poctivá, hesla si ukládala bokem (a třeba interně používala třeba onen moderní SCRAM-SHA1) a je to. Už znají vaše heslo i pro X dalších služeb. A vy o tom ani nevíte. Jediná cesta je tedy používat pro každou službu unikátní heslo.
Pokud má tedy někdo obavu o bezpečnost svého hesla, nemůže toto hodit na provozovatele té služby. Pokud ano, znamenalo by to donutit X provozovatelů zavést bezpečnější metodu (ale zase ne tak úplně bezpečnou ;-) ehm sorry, už to fakt nebudu zmiňovat). Už jen to je hromada práce. Úplně zbytečné, a zcela bez kontroly. Stačí jeden nepoctivý.
Výhody hesel v plainu
Moc jich není. Jednou z výhod mít uloženo hesla v plainu je možnost poslat heslo uživateli, který je zapomněl. V takovém případě je ale lepší ze strany služby stejně vygenerovat heslo nové a to mu poslat. Už jen proto, že uživatelé svá hesla nemění příliš často (a o tom, že by měla entropii 112b si můžeme nechat jen zdát), tak tohle je příležitost jak to trochu napravit.
Dále se tím zjednodušuje implementace. Sice jen trochu, ale proč si přidávat práci. Navíc, co se týče haší, spousta lidí se, i dnes, po 10 letech od prolomení MD5 (v roce 2005 šlo vygenerovat dva různé pdf soubory se stejnou hashí, dnes je možné provést kompletní brute force attack na heslo za 15Kč) bude do krve hádat, že MD5 je pro jejich použití bezpečná. Není. Bezpečná není SHA-1. O bezpečnosti SHA-2 se vedou diskuse, a mezitím se projistotu používá výhradně SHA-512 s patřičně zkráceným výstupem (SHA-2 je sice oslabená, ale SHA-512 je tak „velká“ že i v oslabení bohatě stačí pokrýt bezpečností sílu; také už skončil závod o SHA-3, takže máme k disposici moderní a bezpečnou kryptografickou hashovací fci).
Tím, že použijeme plain, si celé tohleto ušetříme.
Proč se používají stejná hesla
Každý (snad, doufám) ví, jak se to dělá správně. Každý si určitě uvědomuje, že používání stejných hesel pro spoustu služeb je špatná praktika. Přesto to lidé dělají. Jako já to dělám taky. Ale jen tam, kde na ničem nezáleží.
Proč. Protože dneska každá kravina potřebuje přihlášení. Mnohdy úplně zbytečně, je to tam prostě proto, že to jde. Na takové služby opravdu nebudu používat unikátní hesla, protože žádná data nechrání. A když dojde k prolomení, tak je mi to fakt jedno. Maximálně někdo napíše komentář mým jménem, ať si to užije.
Edit po zveřejnění článku: tuto situaci mohou zlepšit provozovatelé služeb. Dnes je situace taková, že hromada webů nabízí pouze vlastní způsob autentizace (navíc každý pes jiná ves). 60 webů, 60 autentizačních údajů, 60 hesel. Někde chtějí email (kdo si má pamatovat jaký), někde login, někde PIN. Pro člověka nereálné k zapamatování. Používáním metod jako OpenID (neplést s MojeID) by stačilo mít pouze jeden autentizační údaj a přihlašovat se k mnoha službám. Služba se k heslu při autentizaci openid vůbec nedostane, takže nepoctivý provozovatel má smůlu. Tím, že by to heslo bylo pouze jedno, by mohlo být složitější (1x 24 znaků si snad ještě pamatuju, 60x 24 ani omylem).
Čemu ale nerozumím je, proč po každém takovém případě (a že jich ještě bude ;-) ), se lidé rozčilují nad tím, že někdo může jejich heslo znát. To může znát kdykoliv, i v případě, že není tak čestný a nepochlubí se chybou na veřejnosti. To, že o tom najednou víte, by mělo vést spíše k zamyšlení, zda se opravdu něco stalo a pokud ano, tak si tu situaci na své straně vylepšit. Veškeré nástroje k tomu jsou.
Tož tak. Přeji Pinkymu, ať chybku v systému najde a opraví a některým uživatelům jabbimu, ať se nad sebou zamyslí.