Kezdőoldal » Számítástechnika » Programozás » Van értelme a hash hashelésének?

Van értelme a hash hashelésének?

Figyelt kérdés
Nem rég kesztem a php programozást, vb.Net-ben van már tapasztalatom. A kérdésem a következő. Lehetséges az, hogy egy md5-s hash-t tovább hasheljek sha1-el vagy színtén md5-el? És ha igen annak van értelme? Mert végűl is ha a 2 hash-t encryptelik akkor csak azelső hash-t kapják meg nem? Jah és mág valami... Ha lehetséges akkor php-ban e milyen módon történik? Csak azért mert én vb-ben functionel csináltam és akkor elég volt md5(md5(md5("String")))) módon elvégezni. Vagy akkor annak se volt értelme? :D

2016. júl. 27. 16:46
1 2
 11/11 2*Sü ***** válasza:

Közelítsük meg a témát lépésről lépésre.


Ha több ezer, vagy több százezer usernek a jelszavát kaparintja meg valaki, akkor biztos lesznek benne olyan jelszavak (md5-el hashelve), amelyeket nyers erővel ki lehet találni. Ha valaki mondjuk egy szerver adatbázisát megszerezte, akkor esélyes, hogy a kódot is látja. Ha mégsem, akkor is játszhat olyat, hogy elkezd végigmenni a 6 karakteres jelszavakon, de nem csak az md5-öt, hanem az sha1-et, md5(md5), md5(sha1), sha1(md5), stb… kombinációkat is végigpróbálgatja. Vagy vannak ugye szivárványtáblák, ami egy nagy md5(str) → str adatbázis. Ezekben meg lehet találni a gyakori jelszavakat, de azoknak valószínű mindenféle kombinációit is. Ergo nem igazán éri meg egymásba ágyazni a hash-eket, mert ráadásul növeli az ütközés esélyét. Amit szoktak ez ellen tenni, hogy „megsózzák” a jelszót. Pl. nem az md5($password)-öt tárolják, hanem az md5($password . md5('ez itt az én saját sóm')). Ez sokat javít a visszafejtés esélytelenebbé tételén.


Ha jelszavakat kell hashelni, akkor nem csak a nyers erő, vagy egy szivárványtábla jöhet szóba. Ha százezer usernek van meg a hash-elt jelszava, akkor erősen valószínű, hogy többen használtak gyakori jelszavakat (password, 123456, stb…). Ezeknek az md5-je is azonos. De az md5(md5(md5($password))) is azonos. Nem is kell visszafejteni, egyszerűen gyakoriság alapján már lehet sejteni, hogy ha egy raklap embernek "5a22e6c339c96c9c0513a46e44c39683" a jelszava az adatbázisban, ez a leggyakoribb, akkor ez valószínű a "password" hash-e lesz, és ezen a statikus besózás sem segít, tök mindegy, milyen módon generálták. Erre megoldás, ha a só nem fix, hanem valamilyen adatból generálják, mondjuk az user id-jéből, nevéből, email címéből.


De még ez sem a legszerencsésebb, hiszen a hacker is gondolhat erre, ő is kísérletezhet vele. Meg alkalmasint ezek az adatok meg is változhatnak, és nem lehet automatikusan újragenerálni a jelszavak hash-ét, hiszen nem ismerjük az eredeti jelszót. De lehet azt is csinálni, hogy generálsz egy véletlen szöveget, vagy az aktuális időbélyegből, IP-ből összegyúrt valamit, és azzal sózod be a jelszót, és lemented az így kapott hash-t is, meg a sót is.


~ ~ ~ ~ ~ ~ ~


És akkor utolsó lépésként fogjuk meg az egészet, és felejtsük el. Mi a probléma? Az md5, sha1, sha256 és társaik mind-mind általános célú hash algoritmusok. Mondjuk használják ellenőrzőösszegnek is, és ott nagyon fontos, hogy gyorsak legyenek ezek a hash algoritmusok, hogy mondjuk egy több száz MB-os fájtból gyorsan lehessen hasht generálni. Pont ezért elemi utasításokkal operálnak, nagyon jól gyorsíthatóak mondjuk GPU-val, párhuzamosíthatóak. De ez a probléma velük a jelszó hashelésénél is, hiszen túl gyorsak, túl gyorsan lehet kipróbálni rengeteg jelszót. Ergo a jelszavak titkosításához olyan hash algoritmust lenne érdemes használni, ami kimondottan lassú, nem elemi utasításokból áll, nem gyorsítható GPU-val, nem párhuzamosítható, időigényes.


A PHP 5.5-től (ha jól rémlik) vezettek be egy külön függvénygyűjteményt, ami pont ennek ad egy keretet. Lásd: [link] . Ez egyelőre a bcrypt eljárást használja. Kicsit eltérő a használata a megszokottól.


A password_hash generál egy hash-t. Abban testre szabható a generáló algoritmus, és annak az „ára”, hogy mennyi processzoridőt zabáljon fel. Mondjuk így:

$options = array('cost' => 12);

$hash = password_hash($password, PASSWORD_BCRYPT, $options);


Ha ugyanabból a jelszóból újra generálsz egy hash-t, akkor az egészen más lesz. Tehát az ellenőrzés sem a megszokott lesz:

if (md5($password) == $password_hash_in_database) …

Hanem kicsit fordítva ülünk fel a lóra:

if (password_verify($password, $password_hash_in_database)) …


(Persze az adatbázisból való lekérés is módosul, ha valaki addig úgy csinálta, mondjuk SELECT * FROM users WHERE name={$post_user_name} AND password={md5($post_user_password)}. Itt csak a bejelentkezési nevet/email címet/azonosítót kell feltételül megadni, a jelszó hash-ét később ellenőrizzük.)


Ha finomhangolni kell a rendszert, túlságosan lelassítja a túl magas cost a rendszert, vagy éppen túl gyengék a jelszavak, és erősebb cost-ot akarunk beállítani, akkor ezt is lehet ellenőrizni:

$options = array('cost'=>10);

if (password_needs_rehash($password_hash_in_database, PASSWORD_BCRYPT, $option)) {

/**/ $new_password_hash = password_hash($password, PASSWORD_BCRYPT, $options);

/* Ezt aztán lehet update-elni az adatbázisban */

}


Ez a megoldás minden szempontból ideális, faék egyszerűséggel használható.

2016. júl. 28. 00:48
Hasznos számodra ez a válasz?
1 2

Kapcsolódó kérdések:




Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!