Navíc pokud je challenge-response správně udělaná (např. na server se nikdy nepošle heslo, ale jenom jeho osolený hash), odpadá ta šaškárna s hashováním hesel na straně serveru (která sice pomůže v tom, že heslo není uložené v databázi, ale přesto ho server dočasně zná během přihlášení, takže ho stejně může uložit) a je to mnohem bezpečnější. Má to jediný drobný háček: i když takové protokoly existují už nějakých 20 let, podpora ve webových prohlížečích je strašlivá.
Je smutné, jak se řeší obezlička v hashování na straně serveru, když existuje mnohem lepší a skutečně bezpečné řešení.
Challenge-response - nejsem problematiky znalý, tak se zeptám - když potřebuji na klientovi zadané heslo zahešovat (se solí), aby po drátech k serveru lezla jen heš a ne čitelné heslo, tak musím ono hešovaní na klientovi nějak realizovat - jak? - javascriptem? - vždyť to je krásně čitelný jazyk a algoritmus si můžu "přečíst". (Ano, u samotných jednosměrných algoritmů, jako MD5 SHA apod. by to principiálně nemuselo vadit, ale pokud takto prozradím způsob solení, je to pomůcka.) Za další - co když nemám na serveru heslo nikde v čitelné podobě uloženo - vše specificky osoleno a zahešováno a takto uloženo v DB? Prostě buďto něco nechápu, nebo se to celé spoléhá jen na neprolomitelnost použitého algoritmu gererování heše, kdy samotný algoritmus může být znám (kde neprolomitelnost jaxi taky není 100% - jak rainbow-tables, tak jiné metody ...) a ještě bych implementací v JS prozradil formu solení pro reálně uložená data v DB. Zkuste mne navést - fakt jsem někdy natvdrlejší.
Přesně tak. Zvlášť když autor zmiňuje i možnost útoku zevnitř.
Zajímalo by mě, kolik eshopů dělá nezávislá code-review a má správně pořešenou vnitřní bezpečnost a deployment tak, aby zdivočelý vývojář (sysadmin) nemohl do kódu skrýt nějakou funkci, která bude odkládat nešifrovaná hesla bokem.
Navíc v době virtualizace musíme věřit nejen adminovi virtuálního serveru, ale i adminovi železa, na kterém to reálně běží.
Reálně stejně nemá uživatel jednoho hesla na všechny servery šanci a někde mu uteče.
Přít se s Vámi nehodlám, obecně je však Vaše tvrzení neplatné (a stejně tak moje). Pointa: "Metoda výzvy a odpovědi bez šifrování pro účely zde diskutované obecně nepostačuje."
Viz např. http://security.stackexchange.com/questions/8896/challenge-responce-and-man-in-the-middle
Uvažujete dobře. Současná kryptografie se opírá o sílu vhodných matematických funkcí, které ale nejsou utajovány (výjimky by se ovšem našly). Utajována jsou pouze příslušná hesla. Mimochodem, stejná filosofie platila i pro známý německý druhoválečný šifrovací stroj Enigma.
Cílem solení je vulgárně vyjádřeno zamezit tomu, aby se poznalo, že si různí uživatelé zvolili tatáž hesla - to by pak vyšly i stejné heše. Takhle se vygeneruje náhodná sůl, tj. u každého nějaká jiná, přidá se k heslu a celé se to prožene jednosměrnou funkcí, výsledkem je heš. Sůl se neutajuje, třeba u HP-UXu bývala uložena společně s heslem, resp. s výslednou heší, v souboru /etc/shadow.
Pro stejná hesla tedy vyjde různý výsledek a protože je hešovací funkce jednosměrná, nemůžete zpětně odvodit, čím k onomu výsledku (tj. k heši) přispěla sůl a čím heslo.
V extrémním případě, stejná sůl + stejné heslo, by pochopitelně vyšla i stejná (nebo stejný?) heš.
Takto implementované je to k ničemu, to je ale jenom ta "response" část z "challenge-response". Challenge může být třeba několik náhodných znaků které server vygeneroval a platí jenom 5 minut nebo jedno přihlášení a pak se počítá hash(challenge+hash(doména+heslo)).
Díky tomu i když ti někdo ukradne ten hash, bude mu k ničemu (protože ho uživatel právě použil).
zjednodusene
vychodzi stav:
a. server pozna pass hash.
b. klient vie login a heslo
komunikacia
1. server posle random string - challenge
2. klient vyrata salted password hash. Salt nema za ulohu zvysit zabezpecenie ale zamedzit pouzitiu rainbow tabuliek. Zvykne sa pouzivat login:password. H(l+':'+p)
3. klient k hashu prida challenge a zahashuje - vytvori response. H(pass_hash+':'+challenge)
4. klient posle response spolu s loginom
5. server zobere hash k danemu uctu a spravi to iste co klient. H(pass_hash+':'+challenge)
Ak sa vysledok zhoduje - klient je overeny. Sietou nepreslo ani heslo, ani zahashovane heslo. Len zahashovane heslo zahashovane challengom. Kedze sa pouzivaju jednosmerne funkcie, je len na neprelomitelnosti pouzitej funkcie ci je prihlasenie bezpecne alebo nie.
Nevyhodou je samozrejme to, ze ak z vnutra unikne zahashovane heslo, je logicky jednoduche prihlasit sa... H(uniknuty_hash+challenge_zo_serveru) = response. Na utok z vnutra je ale tazke hladat ochranu. Aj HTTPS zabezpeci transport po nedoveryhodnej sieti len ak su obe strany spojenia bezpecne. S keyloggerom alebo podplatenym adminom serveru je k nicomu.
Podrobnejsie napriklad na http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol
Prima - tento postup byl ten, který jsem předjímal v minulém postu, kdy mi vadilo, že bych musel na klientovi ukázat, jak se tvoří heš na serveru (třeba ten váš příklad H(l+":"+p)) a to mi připadalo docela divné a nepříjemné až nepřijatelné - tedy za paředpokladu, že by ona klientská část byla řešena mnou zmiňovaným javascriptem (protože jiné způsoby "programování" na klientovi neznám), který není možné před uživatelem skrýt. Ty dále v reakci od Jedny zmiňované metody (HTTP Digest nebo SCRAM) vůbec neznám.
to ze vidite ako to funguje je uplne irelevantne. Bezpecnost nie je tvorena obskuritou riesenia ale jednosmernostou hashovacej funkcie. Mozete poznat ako bol hash vypocitany, akou funciou, co v nom cca je a mozete poznat vysledok. Aj-tak vam to ale nepomoze vytvorit dalsi response tak aby ho server akceptoval. Mozete len typovat, ale skor uhadnete nejake 20 miestne heslo ako 64znakovy vysledok SHA2 response :) To je princip kryptografie.
> jak? - javascriptem?
V žádném případě. Ovšem ne z toho důvodu, že by snad vadilo, že se útočník dozví, že se používá SHA-2 (security by obscurity nefunguje), ale z toho důvodu, že JavaScript se načítá z nedůvěryhodného serveru, takže mu uživatel heslo zadat prostě nesmí.
Tyhle věci musí podporovat přímo prohlížeče. Například HTTP Digest nebo modernější a bezpečnější SCRAM.
> Za další - co když nemám na serveru heslo nikde v čitelné podobě uloženo - vše specificky osoleno a zahešováno a takto uloženo v DB?
To je přece cílem - čitelně heslo od uživatele vůbec nedostat!
> Prostě buďto něco nechápu, nebo se to celé spoléhá jen na neprolomitelnost použitého algoritmu gererování heše, kdy samotný algoritmus může být znám
Ano, spoléhá, a ano, všechny bezpečné šifrovací algoritmy jsou samozřejmě známy.
> kde neprolomitelnost jaxi taky není 100% - jak rainbow-tables, tak jiné metody
Rainbow tables ti nepomůžou, když sůl bude podstatně větší než rozsah, který si v rainbow tables můžeš dovolit. Prakticky realizovatelná rainbow table pokryje maximálně tak 2^80 hodnot, sůl může mít třeba 128 bitů.
> tak jiné metody
Samozřejmě že když někdo prolomí SHA-2, tak jsi v pr…. Ale to budeš stejně, protože na tom závisí spousta dalších systémů.
Podle mne nejlepší varianta je, když to solení a hashování provádí prohlížeč. Jako uživatel mu stejně důvěřuju, prohlížeč má nejlepší možnost chránit uživatele při zadávání hesla (pokud heslo zadávám do webové stránky, vždy ji může jiná stránka napodobit; pokud ho zadávám do speciálního okna prohlížeče, může to být udělané tak, že to žádný web napodobit nedokáže). Navíc by se mělo řešit i odhlašování, což se opět nejlépe udělá v prohlížeči.