Na to není potřeba mít plaintext heslo uložené, ale můžete tuhle operaci (převod hesla ze starší hashovací funkce na novou) udělat při nejbližším dalším přihlášení daného uživatele - protože tehdy on to heslo stejně zadává a máte ho tedy dočasně v nehashované podobě.
Takto to i dělají některé frameworky, když postupně přecházejí na čím dál tím bezpečnější hashovací algoritmy. A dokonce kvůli tomu v databázi ani nemusí mít víc sloupečků - v tom jednom, kde je hash hesla, tak před vlastním hashem hesla je třeba string: "md5:", "sha1:", "sha256:", "bcrypt:"...
No možností je víc. Buď je neřešíte vůbec (a prostě mají heslo hashované méně bezpečnou funkcí - ale takových uživatelů bude asi obecně méně - a u eshopů navíc někdo, kdo třeba delší dobu od nich nic nenakoupil je asi také méně zajímavý), nebo jim to heslo zneplatníte - a díky tomu, že máte jejich mailovou adresu, tak si můžou nastavit heslo nové (buď je o tom informujete mailem, nebo při pokusu o další přihlášení). Taky můžete účty, na které se nikdo nepřihlásil třeba 3 roky rovnou smazat...
Prave na to jsem narazel. Pokud se neresi nic, tak to neresi ani problem Mallu (stare ne bezpecne hashovane hesla). Z hlediska eshopu si umim predstavit i situaci, kdy je zajimava i informace, ze se klient vraci po vic nez 3 letech. Takze jedine, co zbyva, je zneplatneni starych (resp. ne bezpecne zahashovanych) hesel. A i to znamena nepohodli pro potencialni zakazniky (napr. ty, kteri si to heslo opravdu pamatovali dobre).
No, podle mně měli takhle průběžně ty hashovací metody měnit za lepší - a teď případně zablokovat účty jen těm, kteří se opravdu nepřihlásily třeba ty 3 roky a víc. Těch by mohlo být řádově třeba 10 %. A určitě by to bylo lepší, než teď s resetem hesla otravovat úplně všechny zákazníky...
I když je taky docela dobře možné, že jim opravdu utekla spíš nějaká starší záloha - a pak je tu ještě to riziko, že i kdyby třeba konkrétní zákazník měl nyní heslo už hashované bezpečně, tak by to bylo to samé heslo, co měl před třeba 6-7 lety a tudíž by ho útočník z té staré zálohy měl také. Takže když teď donutí ke změně všechny, tak to k bezpečnosti určitě spíš přispěje, než aby jí to zhoršilo. :-)
Pokud unikla databáze s hashi, je potřeba změnit všechna hesla, která v té databázi byla, nejen ta se slabým hashem bez soli. To, že útočník pomocí duhových tabulek získá hesla uživatelů je jen jeden z problémů. Další problém je i to, že útočník může znát jiná hesla uživatelů (z jiných úniků), a i při použití silné hashovací funkce nebo soli si může ověřit, že i zde použil uživatel stejné heslo. A pak se samozřejmě může útočník zaměřit na nějaké VIP uživatele a pokoušet se zjistit jejich heslo hrubou silou.
A pak musíte mít v kódu na věky implementaci MD5. Když už chci hesla přehashovávat bez účasti uživatele, uložím si je do databáze i zašifrovaná asymetrickou šifrou, k níž je privátní klíč uložen offline někde bezpečně v trezoru. Až je budu chtít přehashovat, vyndám klíč z trezoru, hesla rozšifruju a zahashuju novým hashem.
Ta MD5 je tam úplně zbytečná, jenom to zbytečně komplikuje implementaci.
To vaše „překvapení“ akorát vypovídá o tom, že nevíte, jak to funguje. U toho hesla by muselo být uložené, že to bylo hashované nejprve MD5, pak SHA-1 a pak bcryptem. Při přihlášení uživatele by se to samozřejmě muselo hashovat ve stejném pořadí.
Heslo přístupné v plaintextu serveru posíláte, tak se nedivte, že ho server má. To zašifrované heslo s klíčem v trezoru je velice bezpečné řešení, dokonce výrazně bezpečnější, než osolený a opepřený hash (a ty jsou bezpečné dost).
Ona kryptografie není zrovna intuitivní, v diskusích najdete spoustu nesmyslů – hlášky jako „hesla v plaintextu je svinstvo“ nebo „MD5 je pro hesla slabá“ jsou sice efektní, ale s realitou nemají nic společného.
Implementaci to sice nepatrně zesložišťuje, ale ono je to spíš k plusu ...
Překvapení znamená, že vím jak to funguje. Proč bych musel mít u každého hesla uložené? Proč bych musel vědět, jak je to zahashované? Vždyť všechny budou stejně ... Mít každé jinak byla blbost i u Mall, jak se ukázalo.
Heslo přístupné v plaintextu posílat serveru nemusím. Alespoň od té doby, co existuje javascript ... Posílám-li, jsem blbej programátor. Používám to i já v systému, který využívá pouhých deset lidí v intranetu.
Implementaci to sice nepatrně zesložišťuje, ale ono je to spíš k plusu ...
V žádném případě. Složitější implementace znamená náklady navíc, větší pravděpodobnost chyby, komplikovanější testování, což často vede k tomu, že to testované není. Výhoda složitější implementace není žádná.
Překvapení znamená, že vím jak to funguje.
Dobře, napíšu to konkrétně:
Spíš se mi líbí překvapení hackera, až po bcryptu bude louskat sha1. Až tam objeví md5, tak mu hrábne ...
Tohle je nesmysl. Hacker nebude objevovat SHA-1 a po té MD5, hacker musí předem vědět, jak ta hashovací funkce vypadá (např. že je to nejprve MD-5, pak SHA-1 se solí – a kde je ta sůl uložená). Vy to popisujete, jako by nešlo o hashování, ale o šifrování, a útočník by odšifroval jednu vrstvu a dostal se k další.
Proč bych musel mít u každého hesla uložené? Proč bych musel vědět, jak je to zahashované? Vždyť všechny budou stejně ...
Takže byste tam měl navěky staré hashovací funkce, které mohou mít vážnou díru která znehodnotí vše za tím. To je opravdu vylepšení… Představte si, že na začátku použijete hashovací funkci, u které se později ukáže, že její prostor hodnot je ve skutečnosti jen 10 – nebo-li že stačí mít 10 různých univerzálních hesel, a ke každému účtu bude jedno z těch hesel platit. Vy na to pak navršíte SHA-1 a bcrypt a SHA-3 a spoustu dalších hashovacích funkcí – a útočník pak přijde, vyzkouší těch deset hesel a jedno z nich bude fungovat. Jak už jsem psal, počítačová bezpečnost není intuitivní – tohle je jeden z příkladů, vy jste měl pocit, jak vrstvením hashů na sebe bezpečnost zvyšujete, přitom vám jí hned ten první hash rozboural a nic nad ním už to nespraví.
Když se na ten seznam podíváte, skutečný průšvih s hesly vznikl až tím, že ta stará hesla nebyla nijak osolená. To, že to bylo MD5, je prkotina – kdyby ta hesla byla osolená, dostali bychom se maximálně k pár heslům nějakých VIP účtů, pro které by se někdo rozhodl, že na ně spustí útok hrubou silou. Rozdíl mezi MD5 a SHA-1 je v tom, jestli těch VIP hesel rozlouskneme 5 nebo 10. Rozdíl mezi nesolenými a solenými hesly je v tom, jestli se rozlouskne pár hesel k vybraným účtům, nebo jestli se rozlousknou všechna jednoduchá hesla. Ano, zase to není intuitivní, kryptografické hashovací funkce jsou tak komplikované, tak by se zdálo, že budou to nejdůležitější, a ona je přitom mnohem důležitější sůl – a hlavně silná hesla.
Heslo přístupné v plaintextu posílat serveru nemusím. Alespoň od té doby, co existuje javascript ... Posílám-li, jsem blbej programátor. Používám to i já v systému, který využívá pouhých deset lidí v intranetu.
Z hlediska uživatele je to to samé – heslo předá vašemu skriptu, a co s ním ten skript udělá, to uživatel neovlivní. Taky samozřejmě záleží na tom, jestli je to v tom JavaScriptu vůbec naprogramované správně. Přístup k tomu heslu mají všechny skripty na stránce, mají k němu doplňky prohlížeče.
Správné řešení pro tyhle případy je takové, že heslo vůbec neopustí prohlížeč jako takový – tj. už v okamžiku, kdy prohlížeč předává údaje webové stránce, skriptu nebo ho posílá přes síť, musí už to heslo být „zakódované“ – např. zahashované se solí.
Prostě nemáš pravdu. Bezpečnost je daná tou poslední (tedy nejsilnější) částí. A prodloužení doby louskání je opravdu výhodou. Dost to vadí brute-force útokům.
A dokonce je i fajn, že útočník nezná správnou kombinaci těch hashů, vidí jen ten nejsilnější. Sice security by obscurity, ale i tak je to prostě zesložištění útoku.
Kdyby byla bezpečnost daná tou nejslabší částí, tak hashe nebudou fungovat vůbec. Protože tou nejslabší částí je právě ten plaintext. Běžné desetiznakové heslo bude složitost cca 26^10. Kdežto MD5 2^128 pro jakoukoliv délku. Možnost kolizí nebo možnost brute force je tedy už naprosto jedno - důležitá je ta první, prozatím bezpečná část. Kolizí v rámci toho plaintextu bude podstatně více (v rámci nějaké větší db).
Ty jsi prostě popsal brute-force ... tím dokážeš napadnout libovolný způsob. Dokonce i ty tvoje asymetrické šifry v trezoru.
Souhlasí se mnou i pan Vrána: https://php.vrana.cz/ukladani-hesel-bezpecne.php
Dokonce i wikipedie: https://cs.wikipedia.org/wiki/Message-Digest_algorithm
Ten poslední odstavec nechápu ... já říkám, že heslo browser neopustí, ty tvrdíš to samé - a přitom mi odporuješ.
Nebo jinak ... pokud souhlasíš, že bcrypt(salt . plainheslo) je dostatečně bezpečné, tak musí být dostatečně bezpečné i bcrypt(salt.md5(heslo)).
Už v komentáři, na který reagujete, jsem vám vysvětlil, proč to není pravda.
Prostě si v hlavě proveď md5 = plaintext.
To jste ovšem učinil ničím neodůvodněný silný předpoklad. Jak jsem psal výše, zkuste si do té vaší rovnice dosadit třeba md5 = const 'a'
. Nebo, aby to nebylo tak průhledné, třeba md5 = substring(plainheslo, 0, 1)
.
Tímto jsem ti podal důkaz a končím diskusi.
Podal jste důkaz, který jsem vyvrátil dřív, než jste ho podal. Diskusi nemusíte ukončovat, stačí ji přerušit do doby, než pochopíte to, co už jsem vám v komentářích napsal.
Prostě nemáš pravdu. Bezpečnost je daná tou poslední (tedy nejsilnější) částí.
Někdo používá matematiku a argumenty, někdo pověry a dokazuje slůvkem „prostě“. Já jsem vám uvedl konkrétní příklad, jak může jedna slabá hashovací funkce rozbít celý řetězec – bez ohledu na to, kde se v tom řetězci nachází. Tím vaším „prostě“ jste to nevyvrátil.
A prodloužení doby louskání je opravdu výhodou. Dost to vadí brute-force útokům.
Nepatrné prodloužení doby louskání je nepatrnou výhodou. Nepatrně to vadí brute-force útokům.
A dokonce je i fajn, že útočník nezná správnou kombinaci těch hashů, vidí jen ten nejsilnější.
Vy si stále představujete, že útočník něco „odhashuje“ a něco se mu objeví. Tak to ale funguje možná tak v CSI. „Útočník vidí jen ten nejsilnější hash“ jen dokazuje, že vůbec netušíte, o čem píšete – protože útočník žádný hash nevidí.
Útočník vidí to, co je v databázi – může tam být jen výstup hashovací funkce, může tam být nějaké označení hashovací funkce plus její výstup. Když bude v databázi 16 bajtů, může si tipnout, že je to MD5, když tam bude 20 bajtů, může si tipnout, že je to SHA-1. Ale stejně tak to první může být 16 bajtů useknutých z SHA-1, nebo to druhé MD5 doplněná o 4 náhodné bajty. Pokud útočník algoritmus hashe nezná, může zkusit, zda to není jednoduché použití hashe s danou délkou výstupu. Pokud útočník algoritmus hashování nezná, má smůlu, a zastaví ho i tak primitivní algoritmus, jako přidat na začátek každého hesla malé „a“ a pak to zahashovat MD4 (sic!). Jenže zabezpečení dat se dělá s předpokladem, že útočník hashovací algoritmus zná.
Kdyby byla bezpečnost daná tou nejslabší částí, tak hashe nebudou fungovat vůbec. Protože tou nejslabší částí je právě ten plaintext.
Jenomže tak to ve skutečnosti je. Když budete mít čtyřznakový číselný PIN, útočníkovi stačí nejvýš 10 000 pokusů na jeho zjištění. A můžete k tomu požít třeba SHA-3 tisíckrát iterovanou, a stejně vám to nepomůže, protože to je jenom deset tisíc možností. Hashovací funkce nedokáže entropii vyrobit, bez ohledu na to, jakou krkolomnost si vymyslíte.
Běžné desetiznakové heslo bude složitost cca 26^10. Kdežto MD5 2^128 pro jakoukoliv délku.
No jo no, jak už jsem několikrát psal, bezpečnost není intuitivní. Vaše představa, jak se louská MD5 a postupně na obrazovce nabíhají jednotlivé znaky hesla, jak to vídáte v televizi, neodpovídá realitě. Hashe hesel se „louskají“ tak, že zkoušíte jedno heslo za druhým, pokaždé pro něj spočítáte příslušný hash, a porovnáte jej s tím hashem, který máte v databázi. Případně to nemusíte počítat, pokud už ty hashe někdo spočítal před vámi a vytvořil z nich databázi, ve které je jenom hledáte. Takže když budete vědět, že heslo má 10 malých písmen, je to složitost pořád 2610, protože budete generovat jednotlivá hesla. Délka hashe počet zkoušených variant nijak neovlivní – pořád musíte vyzkoušet maximálně 2610 hesel, ať jsou zahashovaná MD5, SHA-1 nebo čímkoli jiným.
Ty jsi prostě popsal brute-force…
Jistě, co bych měl popisovat jiného? Metoda hrubé síly je jediná metoda, kterou je možné získat heslo „z“ hashovacích funkcí MD5 nebo SHA-1. Ani u jedné z těch funkcí není znám útok, který by uměl hledat kolize 2. řádu (což by byla možnost, jak ten útok urychlit). Resp. u MD5 myslím nějaký teoretický koncept existuje, ale nebylo to ověřeno v praxi, protože je to zatím příliš nákladné.
tím dokážeš napadnout libovolný způsob. Dokonce i ty tvoje asymetrické šifry v trezoru.
Jo. Když budete mít v databázi uložené svoje heslo, které bude zašifrované jenom kilovým klíčem, vytvoříte si první klíč a zkusíte jím své zašifrované heslo dešifrovat – když dostanete to vaše heslo, máte klíč, když nějaké náhodné smetí, máte špatný klíč a zvolíte si další. S pravděpodobností 50 % najdete správný klíč už po vyzkoušení 21023 klíčů.
Souhlasí se mnou i pan Vrána, Dokonce i wikipedie
Tomu se říká Dunningův-Krugerův efekt. Na to, abyste dokázal porovnat vaše výroky s těmi odkazovanými texty, byste potřeboval nějaké minimum znalostí. Kdybyste ty znalosti měl, nepsal byste „útočník vidí nejsilnější hash“.
já říkám, že heslo browser neopustí, ty tvrdíš to samé - a přitom mi odporuješ
Podstatné je, jak je to z pohledu uživatele. Uživatel zadá heslo do webové stránky – tedy ve vašem případě musí počítat s nejhorším případem, a to takovým, že heslo prohlížeč opustí. Uživatel těžko bude pokaždé kontrolovat vaše skripty, aby si mohl být jistý, že fungují správně a že se heslo z prohlížeče skutečně nikam ven nedostane.