Hogyan hasheljünk?
Úgy tudom, hogy jelszavak titkosításához ma már közel sem elég, ha simán csak valamelyik hash függvénnyel kódoljuk, mert a szivárvány táblák segítségével a kódolt jelvszavak egy része seperc alatt visszafejthető… A problémára talán a legjobb megoldás, ha hashelés előtt jól megsózzuk. Az érdekelne, hogy melyik a legjobb választás a hashelési módszerek közül.
A kérdéseim:
És hogy illusztráljam a lehetőségeket:
Szerintem:
Szerintetek melyik a legoptimálisabb megoldás, ha szem előtt tartjuk a biztonságot és a sebességet egyaránt?
■ A kérdéseim:
- Hány sót használjak? Elég egy, vagy legyen a jelszó előtt és után is?
- Mit és hányszor kódoljak?
- Használjak esetleg két különböző hash függvényt?
- Kódoljam a jelszó hash-ébe mondjuk a felhasználónevet is?
És hogy illusztráljam a lehetőségeket:
md5($pass.$salt)
md5($salt.$pass)
md5(md5($pass))
md5(md5(md5($pass)))
md5(md5($pass).$salt)
md5(md5($salt).$pass)
md5($salt.md5($pass))
md5($salt.$pass.$salt)
md5(md5($salt).md5($pass))
md5(md5($pass).md5($salt))
md5($salt.md5($salt.$pass))
md5($salt.md5($pass.$salt))
md5($salt.md5($pass).$salt)
md5(sha1(md5(sha1($pass))))
md5($username.md5($pass).$salt)
md5(md5($username.$pass).$salt)
sha1($salt.$pass)
sha1($username.$pass)
sha1($username.$pass.$salt)
sha1($salt.sha1($salt.sha1($pass)))
Szerintem:
md5($salt.md5($username.$pass).$salt)
Szerintetek melyik a legoptimálisabb megoldás, ha szem előtt tartjuk a biztonságot és a sebességet egyaránt?
$hash =
Azért örülnék, ha még a
használd azt amit gex írt.
üdv,
Balázs
Szóval érdemes kombinálni a
Mért jó az, ha a hash-be belekódoljuk a jelszó hosszát? Azt még megértem, hogy mondjuk adatbázisban tároljuk a jelszó hosszát, és az alapján tudjuk ellenőrizni, hogy megfelelő jelszót adtak-e meg, avagy csak véletlen egyezik a hash...
Nem jobb, ha előre is teszünk saltot, és nem csak a végére?
Nem!
A sózás nyilván itt segít, lehet mindenféle trükkös dolgot kitalálni, de tényleg szükség van rá? És ha igen, biztos lehetsz benne, hogy a trükkösen kitalált hash függvényed nem éppen ellened dolgozik? Mert ha sózol valamit, viszont kétszer hashelsz, akkor azt kellene bizonyítanod, hogy a sógeneráló random függvényed jobban véletlenszerűsít, mint amennyit a kétszeres hashelés elvesz a térből.
Mindezt nem azért mondom el, mert a weben általánosságban szükség lenne olyan übersecure megoldásokra. Kaptam én olyan kérést ügyféltől régebben, hogy álljunk át plain text jelszó tárolásra, hogy az elfelejtett jelszónál a régi jelszavát lehessen neki kiküldeni. Fölvilágosítottam a veszélyekről, azt mondta, rendben. Ez ilyen, a leggyengébb pont még mindig a felhasználó, aki fölírja a monitorra, DOC fájlba, stb a jelszót.
Ha már kriptográfiával szeretnél foglalkozni, akkor keress egy szimpatikus hash függvényt. Egyébként én a crypt függvényt szoktam használni, azzal egyszerű hashelést váltani.
Disclaimer: ez mind azon alapul, amit az egyetemen fölszedtem. Nem űzöm napi szinten a kriptográfiát, szóval jó lenne, ha valaki hozzáértő megnézné a dolgot.
gondolkozzunk együtt
Példa: sha1(md5($pass))
desifrírozás (ha tudjuk az sifrírozás lépéseit):
1, Találj egy olyan md5 hasht amiből ez a sha1 hash lesz. (az összes md5 kulcsot kell csak végigpróbálni, de végig kell próbálni)
2, (Megvan az md5 hash.) Találj egy olyan kulcsot ami ezt az md5 hash-t adja.
Szóval még ha tudjuk a hashelő algoritum lépéseit akkor is az első lépés plusz egy lépés volt a kódfejtőnek, egy szimpla md5($pass) szemben. De ha nem tudja hogy a sha1-en belül mit büvészkedtünk akkor nem csak az md5 kulcsokat kell végigellenőrizze.
üdv,
Balázs
...és a fejlesztő...
... aki azt hiszi, hogy 1-2 babona alapú trükk miatt elhagyja az alapvető input ellenőrzést és figyelembe se veszi, hogy mondjuk egy ' OR 1=1 "jelszóval" is be lehet lépni bármelyik userrel.
Láttam már olyan kódot, ahol az alkotója szentül meg volt győződve arról, hogy milyen trükkösen kivédett mindent, holott csak a szerencséjének köszönhette, hogy az utána lévő kódot úgy írta meg, hogy kiessen a nem megfelelő adat.
Egyébként az userek jó részének jelszó elnevezési szokása katasztrófa és sokadszorra se érti meg, hogy miért nem jó jelszó az 1234. Ilyenkor meg teljesen mindegy, hogy hogy van sózva, faragva a jelszó hashe.
Kompatibilis hash... :)
Például OpenLDAP esetén ilyesmi tökéletes:
MessageDigest digest = MessageDigest.getInstance("SHA1");
byte[] hash = digest.digest(password.getBytes());
char[] base64 = Base64Encoder.encode(hash);
String encodedPassword = new String(base64);
encodedPassword = Base64Encoder.encodeString("{SHA}" + encodedPassword);
Nem érdemes ennél jobban variálni, nem ezen fog múlni a rendszer védelme vagy biztonságossága.
md5-ről
nem tudom mire gondolsz szivárvány tábla alatt, de md5-nél nem az a lényeg, hogy ugyanazt a jelszót adja be a rosszindulatú júzer, hanem az a lényeg, hogy egy olyant találjon aminek a lenyomata ugyanaz. úgyhogy ennek - md5(md5(md5())) - az égvilágon semmi értelme, sőt ahogy proclub is írta, még rossz is lehet.
md5-tel esetleg úgy tudod növelni a hatékonyságot, hogy a jelszót darabokra szeded és külön külön készítesz hash-t és az összefűzött hash-t használod.
md5($part1).md5($part2).
kérdés, hogy szükség van-e ilyesmire?
tegyük fel, hogy igazából az md5() a 2^128 variáció helyett gyakorlatban csak 2^32 különböző lenyomatot generál.
2^32 = 4 294 967 296
tehát jó sok :)
ha biztonságra akarsz menni, akkor inkább kezeld a hibás próbálkozásokat (3 rossz próba után időkorlát, ban, stb..), valamint azt, hogy ne tudjon olyan jelszót megadni a júzer, ami szótárral könnyen törhető. esetleg kötelezően adass új jelszót a júzerrel.
én így látom a dolgokat
Nana!
md5($part1).md5($part2)
Ha vmi igazán rossz ötlet, akkor az ez! Nyers erős próbálgatás esetén egyszerűen belátható, hogy ez a módszer balgaság. Tegyük fel, hogy csak számokat tartalmazhat a jelszó és 4 karakteres! A variációk száma ebben az esetben: 10 x 10 x 10 x 10 = 10 000 . Ha ez van hash-elve, ennyit kell próbálkoznom maximum. Most ha ezt 2 x 2 karakterre bontom és azt tárolom el, akkor a próbálkozások száma drasztikusan lecsökken: 10 x 10 + 10 x 10 = 200!
Azt meg nem ér mondani, hogy "de ehhez tudni kell, hogyan működik", mert a dolognak úgy is biztonságosnak kell lennie, hogy mindenki tudja, hogyan működik.
Ez meg kicsit szezon-fazon. Az adatbázisban azért kell elkódolni a cuccot, hogyha ahhoz bárki hozzáfér (akár évek múltán), akkor se tudja kitalálni, hogy milyen jelszavakat használtak a user-ek. És mivel konkrétan hozzáfér az adatbázishoz, ezért nincs olyan, hogy "próbálkozások száma".
tehát jó sok :)
Nem, nem sok és a megközelítés is elvi hibás. A jelszó hossza és "variációs nehézsége" - hány és milyen karaktereket tartalmaz - határozza meg a törhetőséget nyers erő esetén és nem a hash végeredményének hossza!!! Mert ha a felhasználók 3 karakteres, számokból álló jelszót használnak, akkor egyrészt a variációk száma máris csak 1000, másrészt 99%-uk a 007-et választotta.
A szivárvány tábla egy néhány GB-os "adatbázis", amiben a hash-ek mellé oda van írva, hogy minek az eredménye. Tehát már vki jó előre legyártotta az md5 hasheket '0'-tól 'zzzzzzzzzz'-ig mondjuk és így csak a hashek alapján nagyon gyorsan megtalálható, hogy mi volt a jelszó. Ezért érdemes vhogy módosítani a mezei md5 hash-elést.
md5 hash
16
Nálam
Felesleges elbonyolítani
Egyetlen fontos kritérium van csak tehát a hash-elni kívánt karakterlánccal kapcsolatban. Mégpedig az, hogy rendszeren belül illetve lehetőleg globálisan nézve is egyedi legyen. Ennél több nem kell, attól nem lesz egyedibb a hash alapja, hogy benne az amúgy is egyedi felhasználónév helyett annak md5-ölt változata van ott.
Fontos tudni, hogy a különféle hash megoldások (mint az md5 vagy az sha1) egyik fontos jellemzője az, hogy arra se lehessen következtetni két hash-ből, hogy a alapjuk kicsit, vagy nagyon eltér. Azaz ha csak 1 bit a különbség, vagy akár az összes 75%-a, ugyanúgy teljesen eltérő lesz a hash attól,amit az eredeti bitsorra kapnánk. Gondolom, ennek nem ismerete okozhatja ezeket a többszörös hash-elési hókuszpókuszokat.
Világosítsatok föl légyszi...
Thx!
Dávid
Felvilágosítás
Sózni, saltolni pedig a brute force technika elleni védekezésképp tanácsos: nagy mennyiségű karakterláncot (tipikusan lehetséges jelszavakat egy szótár alapján) előre hashelve az idő- és processzorköltséges számítások elvégzése egyszeri feladat, majd ezek után egy egyszerű keresés kérdése a zagyvalékból megismerni az eredeti jelszót. Véletlenszerű karakterlánc jelszóhoz illesztésével gyakorlatilag új jelszót hozunk létre, ami garantáltan nem szerepel egyetlen szótárban sem.
Mert semmi köze a
Ahogy én csinálom
md5($dynamicSalt . $password . $staticSalt)
.Ahogy fenn már sokan kifejtették, a többszörös hashelés nemhogy nagyobb biztonságot nem ad, de csökkenti a biztonságot.
A kétféle só célja a kétoldalú védelem: ha az adatbázis esik áldozatul támadásnak, és a jelszavakkal tárolt salt ismeretessé válik a behatoló előtt, akkor a globális még mindig védelmet nyújt, illetve fordított esetben, ha a kiszolgáló kompromittálódik, akkor még mindig ott vannak az egyedi saltok (és természetesen a globális sónkra szabott szivárványtáblák ellen is ez véd).
A saltot ASCII 33–126 között képzem véletlenszerűen.
(A fenti megoldás tippként bekerült a Zend Framework kézikönyvébe is.)
Tetszik!
Kb hány karakterből álló sót érdemes használni? Az általad linkelt zendes oldalon 49 karakteres só készült. Nem sok ez egy kicsit?
Érzésre
.
Ehhez mit szóltok?
Indoklás?
Nem saját ötlet
Milyen hosszú a szó?
Unix körökben a crypt függvény használatos valamilyen, de mindenképpen EGY darab hash függvénnyel. Ráadásul ott sokszorta nagyobb a veszély, hogy valaki megszerzi az adatbázist, hiszen vannak lokális felhasználók, akik parancsokat tudnak futtatni.
Egy szóval: crypt, vagy ha erősebb hashelést akartok alkalmazni (pl sha512) akkor saját crypt implementáció (nem olyan borzalmasan bonyolult) és semmi több. (A crypt tartalmazza a sót is.) Egyébiránt javaslom meglesésre az mcrypt extensiont.
Saját crypt írásához az MD5 példája a doksiból:
Az első három karakter a hash típusát jelzi, utána valamennyi a salt, a többi pedig maga a hash. Esetleg ki lehet adni egy unixon a
man 3 crypt
parancsot vagy meg lehet nézni a WikipediátEz nagyon jó
Emlékszem mennyit szívtam vele, amikor még nem csináltam meg az admin felületet a mail rendszeremhez, és a jelszóval szívtam :D és kiderült, hogy szóköz lett volna az utolsó karakter. Azóta kicsit átírtam a generátort, és *.* teszek a végére, hogy tudjam ha van szóköz.
akit érdekel a script: itt letöltheti perlben, vagy php itt
Számomra ebben az érdekesnek
Tárolod
mcrypt?
leggyengébb láncszem
re
e-mail
re
sokkal
2. sok ember használ azonos jelszót különböző oldalakhoz, így ha egyhez megszerzik, jó eséllyel sok másik oldalhoz is megszerzik a hozzáférését.
re
mivel az emailkuldessel mar a biztonsag ugrott (hacsak nem ssl titkositott emailt kuldessz,mert egyebkent egy sniffer-el el lehet kapni az adatokat), en hogy a felhasznalo is boldog legyen inkabb megmutatnam a regi jelszavat.
Alapból, kódoltan tárolsz
Valóban van ennek értelme?
"Minek ez az egész?"
Vagyis mért biztonságosabb a kódolt jelszótárolás, mint a cleartext? (nem fájlban tárolásról beszélünk)
Ugyanis, ha adatbázisban van a jelszó, csak akkor férhet hozzá illetéktelen, ha feltörte az adatbázist. És ha bent van az adatbázisban a jelszó érdektelen. (eltekintve attól, hogy sokan ugyanazt a email/név/jelszó párost több oldalon is használják)
Számomra a biztonság 3 lépésből áll:
1. input ellenőrzés, goto 2
2. input újraellenőrzés, goto 3
3. input ismételt ellenőrzés, goto 1
:)
Esetleg valaki elmélkedett már ezen, meghallgatnám a véleményét.
Eltekinteni?
Te mit szólnál, ha valamelyik oldal adatbázisát feltörnék, ahol regisztrálva vagy, és így megismernék az email címedet/felhasználónevedet, és hozzá a jelszavadat? Átvehetnék a hatalmat a közösségi oldali profiljaid, az email postafiókod és akármi fölött, ahol regisztrálva vagy. (kivéve persze, ha mindenhol különböző jelszót használsz).
egyébként szvsz érdemes a kisebb megbízhatóságú weboldalakon más jelszót használni, mert ki tudja, hogy kezelik a jelszót.
Ebben természetesen
nem feltétlenül
nem lassít, de lehet másfajta hash is
sha1(base64_encode(md5($pass).$salt))
És akkor még bármit ki lehet mellé találni, amitől nem mindenki által használt megoldás (tehát könnyen értelmezhető) lesz.
Vagy a hexa értékeket konvertálhatod még a base_convert() segítségével 36-os számrendszerbe. Stb.
Mellesleg nem kell feltétlenül 32 vagy 40 hosszúnak lennie a hashnek, mert akkor alapértelmezés, hogy előbbi md5, utóbbi sha1.
Azért túlbonyolítani sem érdemes.
sql injection
jó tudni
Összefoglaló
köszi