Tohle se ale míjí s podstatou problému. Když vám někdo řekne, jak ukládá hesla, můžete mu věřit a nemusíte. A i když bude dotyčný mluvit podle svého nejlepšího vědomí a svědomí, pořád se dozvíte akorát to, jak si myslí, že ukládají hesla – jenže v implementaci může být chyba nebo hesla mohou unikat někudy po cestě.
Správné řešení je, že se provozovatel webu heslo vůbec nedozví. Aby to bylo bezpečné, heslo nesmí nikdy opustit webový prohlížeč – prohlížeč ho má zahashovat a posílat jedině hash (i při registraci).
Tlačit na provozovatele, aby prohlásili, že hesla hashují, povede k jedinému – provozovatelé prohlásí, že hesla hashují. Ostatně to, že v roce 2016 není přihlašování pomocí hashů standard a že ani neexistuje norma pro registraci, která by provozovateli webu nezasílala heslo, ale jen hash, to je ostuda všech lidí „od webu“.
Prave jste porusil prvni pravidlo kryptografie - don’t roll your own crypto. Opet se vyjadrujete k necemu, cemu nerozumite.
Pouhym hashovanim hesla jen problem odsunete, ale nevyresite anavic podlehnete falesnemu pocitu bezpeci. Na Zero-knowledge password proof se daji tu jsou ruzne Digest Authentication, CRAM-MD5, Secure Remote Password protocol...
myšlenka to je hezká, ale v praxi nic takového nefunguje, http digest je závislý na md5, nemá podporu napříč prohlížeči, nepodporuje odhlášení a ani více účtů. Nemluvě o ne neuživatelské přívětivosti přihlašovacích formulářů v prohlížečích.
CRAM je založen na md5 a není moc rozšířený a pro mě je již mrtvý, z rodinky Challenge–response se ale používá třeba CHAP nebo RADIUS, ale pouze v uzavřených skupinách, nic pro otevřené weby, potřebuje SW na klientské straně. Na webu jsou za mě dobře použitelné deriváty nad oAuth s OTP.
Tady je důvod, proč DANE nepodporuje Chrome
"Some years ago now, Chrome did an experiment where we would lookup a TXT record that we knew existed when we knew the Internet connection was working. At the time, some 4–5% of users couldn't lookup that record; we assume because the network wasn't transparent to non-standard DNS resource types."
DANE je vyšší úroveň zabezpečení jedině v případě, kdy máte certifikát vydaný uznávanou certifikační autoritou, a DANE vás chrání, aby vám někdo nepodstrčil certifikát vydaný jinou důvěryhodnou certifikační autoritou. Takže útočník by musel umět vystavit falešný certifikát důvěryhodnou certifikační autoritou a zároveň umět zahodit váš DNS dotaz. To už je hodně schopný útočník.
Navíc pokud nebudou fungovat TXT záznamy, nebudou nejspíš fungovat ani DS záznamy, a prohlížeč prostě může uživatele upozornit, že nějaká bezpečnostní funkce je vypnutá.
A do třetice, když může zrovna Chrome tlačit na podporu HTTPS, na opuštění slabých algoritmů, na podporu IPv6, proč by nemohl tlačit na to, aby sítě nekazily DNS?
Já za ignorováním DANE a DNSSEC vidím jiný důvod – Google to nepotřebuje, protože pár svých certifikátů si dá přímo do prohlížeče.
Jenda: nedochazi, dane nema s siforvanim jako takovym nic spolecneho, dane rika, ze pokud jste na https, tak toto je ten jediny spravny certifikat. Zadna CA pak nemuze vydat jiny.
MS: HPKP je v tomto ohledu naprosto knicemu. Stejne jako HSTS. Oboje je naprosto technicky nesmyslna technologie. Jedno i druhe je o tom, ze si browser bude pamatovat databazi miliard webu. Hole silenstvi.
Ano, jiz vidim reseni ala google ... zeptejte se nasi jedine duveryhodne databaze ...
> dane rika, ze pokud jste na https, tak toto je ten jediny spravny certifikat. Zadna CA pak nemuze vydat jiny
Já to chápu. Ale pokud jsem útočník a mám v ruce falešný certifikát, k jeho použití potřebuju MITM na uživatelovo připojení -- čímž téměř určitě získám i MITM na jeho DNS dotazy.
Můžeš nadhodit nějaký scénář útoku, kde DANE, které se samo deaktivuje, když se TXT nepodaří přeložit, pomůže?
Pokud bychom se bavili o skutečném certifikátu (OV nebo EV), ne o parodiích na certifikáty (DV), pak žádný MitM není potřeba – vlastník domény třeba www.komercni-banka.cz nemusí nijak útočit na síťové vrstvě, jemu „stačí“, když se mu podaří získat certifikát na jméno „Komerční banka a. s.“ a nasměruje uživatele na svůj web třeba e-mailem.
Ale to se bavíme o certifikátech jak mají být, o uživatelích, kteří vědí, že u důležitých webů musí být certifikát na jméno a ne na doménu, a o situaci, kdy je DANE stejně k ničemu. V reálném světě je to pořád stejné, když se útočníkovi podaří „vypnout“ HTTPS, DNSSEC nebo DANE, oslabuje tím zabezpečení – takže prohlížeče musí přitvrzovat v tom, jak důrazně varují uživatele, že je něco nestandardní, což zároveň tlačí na provozovatele sítí, aby u nich aspoň HTTPS, DNSSEC a DANE fungovalo normálně.
Instead, for this we have HPKP
Ano, jak jsem psal, Google má pro sebe řešení. Ale HPKP není řešení pro celý web, protože na spoustu webů chodí uživatelů výjimečně nebo tam jdou poprvé. HPKP by bezpečně fungovalo jenom tehdy, když by uživatel měl v prohlížeči certifikáty od všech existujících webů. Navíc když už máme útočníka, který dokáže vystavit falešný důvěryhodný certifikát a stornovat DNS dotaz, je pro něj zahození HPKP hlavičky trivialita.
Předávání hesla v otevřeném tvaru provozovateli webu a spoléhání na to, že ho nikdo cestou neodposlechne, že ho nezneužije provozovatel a že s ním dokáže pracovat tak, aby ho nezneužil někdo jiný, to také nefunguje. Rozdíl je v tom, že standardizovat nějakého nástupce HTTP Digest jde a není to tak složité, donutit všechny provozovatele webu, aby s hesly zacházeli bezpečně, je nemožné. Mimochodem, i HTTP Digest s MD5 by byl milionkrát lepší, než se přihlašovat webovým formulářem a session cookies.
To, že to uživatelé nepoužívají, je klíčové. Bezpečnost se dá zvýšit jedině tak, že se typické chování uživatelů učiní bezpečným, ideálně tak, aby to pro uživatele neznamenalo komplikaci. Dát uživatelům možnost chovat se bezpečněji je skoro k ničemu.
Ony v tom mají prsty i autoři prohlížečů, protože jejich password manažery nejsou zrovna uživatelsky přívětivé a například zcela postrádají funkci generování hesel. A další problém je opět v přihlašování přes formuláře – jak má chudák prohlížeč hádat, co je heslo k webu a k jakému webu. Kdyby se používala HTTP autentizace, je to pro prohlížeč mnohem jednodušší.
Nebojte, já jsem pochopil, jak to David Grudl myslel – to jedno heslo v otevřeném tvaru, které je pro uživatele důležité, je heslo k password manageru, a to se nikam neposílá. Heslo k příslušnému webu pak může být nějaké generované, které uživatele nezajímá.
„Běžné“ přihlašování pomocí hashe funguje tak, že se z uživatelského hesla nějakou jednosměrnou funkcí odvodí hash, kterým se uživatel autentizuje. Passsword manager funguje vlastně stejným způsobem, akorát že ta odvozovací funkce není žádná kryptografická funkce, je to prostě mapa web:heslo.
Tohle moc nechápu. Pokud jediné, co odejde z prohlížeče, je hash, čím se to liší od situace, kdy jediné, co odejde z prohlížeče, je heslo? Ano, ten hash je sice výrazně silnější heslo než password123, takže ho asi nikdo neuhodne, ale pokud někdo odposlouchává komunikaci či pokud protistrana ten hash uloží tak, jak přijde (což by se imho stávalo častěji než ukládání plain hesel dnes, protože leckomu by přišlo zbytečné hashovat hash) a ta databáze unikne, jste na tom stejně. Přijde mi, že řešíte jen brute-force attack, což ale opravdu není vše.
Navíc mě napadá další problém, který ale možná má nějaké řešení, rád se ho dozvím. Uživatelé svůj účet chtějí používat v různých prohlížečích na různých zařízeních, přičemž všude by platilo, že pokud zadají své heslo, musí z toho vypadnout stejný hash (ten, který byl vypočítán při registraci, opomíjím situace, kdy by bylo možné říct, že dva různé hashe patří stejnému heslu, stejně jako možnost, že by server posílal nějakou sůl, přijde mi, že funkce, která umožňuje říct "ano, tento hash patří neznámému heslu se solí A a tento stejnému heslu se solí B", nebude zrovna bezpečná - ale třeba je tohle právě to, co už bylo vyřešeno).
To ale znamená, že hashovací funkce by musela být univerzální a závislá jen na zadaném heslu. Jenže pak by se daly použít úplně stejné metody pro brute-force attack jako dnes, akorát by se jim předřadila rainbow table pro tuhle funkci.
Když z prohlížeče odejde hash(web+heslo), nezná provozovatel původní heslo. Přičemž znalost hesla je to, co je problematické – protože lidé používají na více místech stejná hesla. Když uniknou hashe pro danou službu, je to problém jenom té služby.
Hashovací funkce má být univerzální, je závislá na heslu a na identifikaci serveru, sůl se nepřidává. Pro vlastní autentizaci se pak vytvoří hash toho prvního hashe a výzvy serveru, takže ani při odposlechnutí komunikace nezíská útočník údaje potřebné pro opakované přihlášení. I když to je při použití HTTPS méně zajímavé. Takhle funguje třeba HTTP Digest, novější protokoly fungují tak, že ani to, co má uložené provozovatel webu, nestačí pro přihlášení.
Mimochodem,i v prohlížeči pak může být místo hesla uložený ten hash (heslo + identifikace webu), takže heslo pak útočník nezíská ani z prohlížeče (může získat ten hash, kterým se přihlásí na ten konkrétní web).
Děkuji za vysvětlení, ale pořád mi to není úplně jasné, pokud vytvořím hash původního hashe a výzvy serveru a ten odešlu při autentizaci, tak aby ho server ověřil, musí být schopen udělat totéž, to znamená, že má ten původní hash někde u sebe uložený v otevřené podobě (či obecně tak, že původní hash získat lze). Je to tak?
Asi je to profesní deformace, ale opřít bezpečnost o to, že se k té databázi nedostane nikdo nepovolaný... Na to bych si fakt nevsadil. A zabránit MITM tím, že někde centrálně uchovávám vše potřebné k autentizaci... Určitě existují prostředí, kde to smysl dává, ale že by jím byl "internet obecně", to mi nepřijde.
Zajímavější by mohly být ty novější protokoly, kde k přihlášení data na serveru nestačí. Nějaký příklad? Takový, který je pořád použitelný pro situaci "uživatel se přihlašuje z mnoha prohlížečů na mnoha zařízeních a jediné, co má k dispozici (a co je tedy přítomno při všech pokusech o autentizaci), je heslo v hlavě", protože to je maximum, co se dá od většiny uživatelů očekávat.
Pro představu, šlo by to implementovat třeba tak, že si na základě hesla vygeneruješ deterministicky RSA keypair (to prvočíslo se velmi zjednodušeně řečeno generuje tak, že uděláš náhodné číslo a pak ho inkrementuješ dokud nenarazíš na prvočíslo -- a to prvotní náhodné číslo můžeš získat jako hash(doména + heslo)) a na server při registraci pošleš jeho veřejnou část. Při přihlašování pak prostě serveru podepíšeš challenge.
Podobný protokol je SCRAM.
"Když z prohlížeče odejde hash(web+heslo), nezná provozovatel původní heslo."
To je pravda, nicméně dnes se toto dá implementovat pouze pomocí JavaScriptu (případně pomocí JavaScriptu a Web Crypto API), což znamená, že provozovatel to heslo pořád znát může. Může totiž svůj JavaScriptu (třeba cíleně) upravit tak, aby browser heslo vlastně nehashoval a poslal v čitelné podobě a nikdo to nezjistí, bohužel.
Dnes se tedy toto nepoužívá, protože stále musím věřit provozovateli, že jeho kód je v pořádku a to se moc neliší od toho, že mu musím věřit, že moje heslo nezneužije. A pokud se ve speciálních případech (správce hesel apod.) něco takového používá, tak se používá protokol SRP, ale pro většinu běžných webů (ať už to znamená cokoliv) se to nehodí už třeba jenom z důvodu náročnosti implementace.
A to je právě ta ostuda, že už na to dávno neexistuje standard a dávno to není implementované v prohlížečích. Protože v tomto případě to technicky vyřešit jde, na rozdíl od prohlášení provozovatele webu, že s hesly určitě ale určitě zachází bezpečně.
Mimochodem, ta implementace v JavaScriptu by pořád byl závislá na session cookies. Výhoda přihlašování pomocí HTTP hlavičky Authorization je i v tom, že řeší problém únosu session, protože je autentizován každý jednotlivý požadavek.