Gyakori tévhit, hogy a hash és a titkosítás ugyanaz. Nem azok. A hash visszafordíthatatlan. Például:
$ echo -n Password123 | md5sum
42f749ade7f9e195bf475f37a44cafcb -
A „Password123” karakterláncot továbbítjuk az MD5 algoritmusnak (algo), amely matematikai műveleteket végez, és visszaadja a létrehozott hexadecimális kódú hasht. Az egyetlen módja annak, hogy ugyanazt a hash kimeneti értéket kapjuk, az, ha ugyanazt az algoritmust használjuk az eredeti bemeneti adatokkal. Ütközés van, de ezt később megbeszélhetjük.
A legtöbb hash algoritmus kimenete rögzített hosszúságú bináris karakterlánc hexadecimális kódolásban. Mások, mint például ebben a példában, base64 kódolású karakterláncot használnak kimenetként. Figyelembe kell venni, hogy a hossz mindig ugyanaz:
{SHA}uNF8eZRJ8jmr8WTjyocRJPVpe7w=
{SHA}lqdu/Zr6o2dgIER8Up1/7lcUtgw=
{SHA}qYUOwLMlDEuukA5HCT4LR1kQzco=
{SHA}MXZBCpyWJ7TTs1w2kgGJslwNwTg=
{SHA}2sAPLaUh9Mz0bI+XxKEg7qyABe8=
TL; DR
Nem szeretnék túl sokat beszélni a titkosításról (mert azok a dolgok a könyvekhez valók), de fontos, hogy képesek legyünk megkülönböztetni a hash stringeket a titkosított stringektől. A titkosítás általában feltölti a stringet, hogy az megfeleljen egy adott hossznak a titkosítás előtt. Ehhez kulcsra (vagy jelszóra) is szükség van a dekódoláshoz. Ha titkosított jelszavakat használ, akkor a string a bemenet hosszától függően változik. Ha egy rakás titkosított jelszót lát, melyek hossza eltérő, akkor valószínűleg titkosítással van dolga, nem pedig hashinggel. Az AES-256-CBC példa titkosított stringeket és a kapcsolódó szöveges adatokat (a kulcs „ASDF”):
foobar | U2FsdGVkX19G+KtytNHdj6yH2AVvX26pEmtunS/PRnU= foobarfoobar | U2FsdGVkX18sPpIvN6nVh68lOUCcb3gR2fKbCCnBxog= foobarfoobarfoobar | U2FsdGVkX1/EOnUt57TCW4Rh0EdNnWX+lDatuQv2xEXXeAeowW0XG/EXJUe9aSUz $ cat encrypted_passwordsU2FsdGVkX19G+KtytNHdj6yH2AVvX26pEmtunS/PRnU= U2FsdGVkX18sPpIvN6nVh68lOUCcb3gR2fKbCCnBxog= U2FsdGVkX1/EOnUt57TCW4Rh0EdNnWX+lDatuQv2xEXXeAeowW0XG/EXJUe9aSUz $ for i in `cat encrypted_passwords`; do echo $i | openssl enc -base64 -d -aes-256-cbc -pass pass:asdf; echo; done foobar foobarfoobar foobarfoobarfoobar
Most valószínűleg azt gondolja: igaza lehet. Ugyanakkor a kulcsanyagoknak hozzáférhetőnek kell lenniük a rendszer számára, ami azt jelenti, hogy lényegében egy szöveges főjelszó valahol megtalálható - akár RSA kulcsok, vagy jelszavak formájában, vagy fájlokban, adatbázisokba beágyazva, alkalmazásokba keménykódolva, vagy a memóriában tárolva.Pfft, senki sem fogja használni az asdf-et a felhasználók jelszavainak titkosítására. ' MD5-öt használnak ugyanabban a sztringben:
foobar | 3858f62230ac3c915f300c664312c63f foobarfoobar | 59faa421729e846dd800dce59943bfc0 foobarfoobarfoobar | 1352aadab322d1a033c27964be0965db
A hash-jelszavak messze nem tökéletesek, sőt, egy kicsit rosszak is, de rosszabbak a titkosításnál, mert azt próbálják elérni. A felhasználók a lehető legalacsonyabb követelményeket választják a gyakoriság tekintetében, és több webhelyen is használhatják őket. Sok „hack” valójában csak a hitelesítő adatok újrafelhasználása. Ha az eredeti kompromisszum a titkosítás használata lenne, akkor a támadónak csak a kulcsot kellene megtalálnia az összes jelszó dekódolásához. A hash esetén legalább annyi erőfeszítésre van szükségük, hogy feltörjék őket.A modern algoritmusokkal, például a sha512crypt, bcrypt, scrypt vagy argon2 használata esetén a hash értéket nagyon nehéz feltörni.
a jelszó előtt egy sztring hozzáadása a hashhez. A só minden hash esetén egyedi kell, hogy legyen, általában véletlenszerűen kiválasztva, mivel a lényeg az, hogy az azonos szöveges „jelszó” hash érték minden alkalommal eltérő legyen. Ez megnehezíti a jelszó feltörését, mert ha 1000 felhasználó „jelszó” szavát ellenőrizni kell, akkor minden felhasználónak egyedi sója van, és ezt 1000 alkalommal kell elvégezni - minden felhasználó/só esetén. Ez azt is jelenti, hogy nem tudják hatékonyan használni az előre összeállított szótárakat vagy a szivárvány táblákat (általában...), mert ezekhez egyedi sóra van szükség.
A weboldalak néha ezt elrontják, és minden felhasználó számára egy közös sót használnak; ez ellentmond a célnak.
Az alábbiakban a sózott SHA1 hash értékek láthatók:
b353977827f67a4ae0318f3a9447fae1c13d9d90:b8d18ca |______________________________________|||_____| hash | salt | szeparátor
A hash kód alapvető szövege „jelszó”. A só értéke „b8d18ca”, és a SHA1 ($salt.$pass) API-t használja. Ez azt jelenti, hogy az algoritmus megkapja a „jelszó” szöveget, létrehoz egy sót, és hozzáadja azt a szöveg elejéhez. Amikor a webhely vagy az alkalmazás a jelszavát ellenőrzi a jövőben, a „jelszó” szöveget adja meg bemenetként, leolvassa a tárolt hash-ben lévő sót, hozzáadja a kiválasztott jelszó elejéhez, és összeveti a létrehozott hash-et a tárolt hash-el. Ha nem tudja, hogy a só egy része, a hash a következő szöveget eredményezi:
b8d18capassword
Mivel az algoritmus szöveges bemenetet használ, a só és a létrehozott hash érték átlátható marad a felhasználó számára. A hash kielemzésekor, ha az algoritmus sóval rendelkezik, tudnunk kell a sót, hogy azt a kiválasztott szöveghez hozzáadhassuk a jelölt szöveg létrehozásakor.
Ha helyesen hajtjuk végre, a sózás még időigényesebbé teszi a feltörést. A véletlenszerű só használatával arra kényszerítjük a Crackert, hogy időt vesztegessen a nem egyező hash értékek feltörésére. Ez nagyjából a device_speed / number_of_salts erőfeszítést igényli, mivel minden sóhoz létre kell hoznunk egy jelöltet. Ha a só statikus, akkor a matematikai számítás ugyanaz... speed_of_device / 1. Egy másik nézőpont:
A mi GTX 980 feltöri a SHA1 ($salt.$pass) 3576,8 MH/s-ban vagy 3,5 milliárd jelöltet másodpercenként A mi hashlistánk tartalmaz 1000 egyedi sót 3,500,000,000 / 1000 = 3 500 000 jelölt másodpercenként
Ez három nagyságrenddel lassabb, és 99,9%-os veszteséget jelent. Statikus só használata esetén ez így néz ki:
A mi GTX 980 crackjeink SHA1 ($salt.$pass) 3576,8 MH/s vagy 3,5 milliárd kandidátus másodpercenként A mi hashlistánk tartalmaz 1 egyedi sót 3 500 000 000 / 1 = 3 500 000 000 kandidátus másodpercenként
Ha ez nem érthető, olvasson tovább, később lesznek szép diagramok...
Egy másik gyakori fejlesztés a "hash this plaintext"-hez képest az, hogy "hash this plaintext, aztán azt is hash-eljük, aztán azt is" több ezer alkalommal.Ebben az esetben, amikor egyetlen jelölt jelszót próbálnak meg feltörni, a jelszó-feltörő programnak több ezer kísérletet kell tennie. Ezt iterációnak, ciklusnak vagy változó költségnek nevezzük. Egyes jelszó-hash algoritmusok rögzített ciklusokat használnak; mások, például a Git, lehetővé teszik ezeket a hash algoritmus részeként. Például az md5crypt() az MD5-et használja, beleértve a sót is, és pontosan 1000 cikluson megy keresztül. A sha512crypt() a sha512-et használja, beleértve a sót is, és a ciklusok száma konfigurálható (alapértelmezés szerint 5000). A
ciklus elsősorban a hash algoritmus számítási költségét befolyásolja, nem pedig a memóriahasználatot vagy egyéb tényezőket. Ezek fontosak bizonyos típusú hash támadások elleni védekezéshez optimalizált algoritmusok tervezésekor, de ez túl bonyolult ahhoz, hogy itt megvitassuk. A
Nézzünk néhány példát a hash algoritmus kiválasztásának hatásaira - legyen az sós, több ciklussal stb. Tegyük fel, hogy a támadó 1000 felhasználói hash értéket gyűjtött egy fertőzött webhelyről, és csak egy egyszerű támadást szeretne végrehajtani, ahol minden jelszó-hash értéket tesztel - 143,2 millió jelölt jelszó. A
fertőzött webhely által használt hash típus nagy hatással lesz a támadás végrehajtásához szükséges időre. Itt egy (relatív, hozzávetőleges) diagram arról, hogy hány másodpercbe telik a támadás befejezése a használt hash típusától függően, ahol a szabványos grafikus kártya esetén:
Hát, ez használhatatlan! A legerősebb hash típusok sokkal lassabbak, de a gyorsabb típusok csak semmivé zsugorodnak.Használjuk ismét a logaritmikus X tengelyt az idő mérésére. Amikor a sávok balról jobbra haladnak, akkor azok a 10 hatványait növelik:
Így néhány lényeges pont: Amikor megpróbálunk feltörni néhány jelszó-hasht, az egykörös kör könnyebb, mint a többkörös, és a sózás nélküli könnyebb, mint a sózással. Ezzel szemben, amikor bizonyos cégek vagy weboldalak bejelentik a felhasználói adatok adatlopását, a) a jelszavakat jobb, ha hashed formában tárolják, nem csak szövegesen; b) jobb, ha sózottak is, nem csak hashed; c) jobb, ha erős, többkörös, sózott hasht használnak, nem csak egyköröset.
Mielőtt megpróbáljuk feltörni egy adott jelszó-hasht, a feltörőnek ki kell derítenie, milyen hash algoritmust használtak a létrehozásához. A hash típusának azonosítása általában egyszerű, de nem mindig. A feltörők általában megalapozottan találgatnak a nyomok (például a hash hossza és formátuma) alapján. Végső soron az egyetlen módja a hash típus helyességének megerősítésének az, ha a hash feltörhető-e.
Itt és itt van néhány kiváló erőforrás ehhez a feladathoz, melyek megmutatják, hogy milyenek a gyakori hash értékek.
A Kali Linuxban elérhető a „hash-identifier” csomag (amit itt lehet megszerezni), mely segít az ismeretlen hash típusok azonosításában.
Amikor két különböző input ugyanazt a hash kimenetet eredményezi, akkor ütközés történik. Ez rossz (nyilvánvalóan).A jelszavak esetén ez azt jelentheti, hogy lehet, hogy nem tudtam feltörni a tényleges jelszavát, de mivel találtam egy olyan bemenetet, amely ugyanazt a hash értéket eredményezi, a szöveges értéket használhatom a rendszer megtévesztésére, hogy azt higgye, a jelszó érvényes.
A Microsoft Office egy olyan algoritmust használ a dokumentumok védelmére, amely évek óta hajlamos a kollízióra. Nem ritka, hogy egyetlen hash esetén több kollíziót is találunk, melyek mindegyike kinyitja a dokumentumot.
Amint felfedezik a kollíziót, az algoritmus gyakorlatilag tönkremegy. Ha egyszer megtörténik, statisztikailag nagyon valószínű, hogy újra megtörténik. Az egyetlen dolog, ami visszatart minket, az az idő és a feldolgozási kapacitás. Ahogy az algoritmusok egyre robusztusabbakká válnak, egyre több kapacitásra és időre van szükség a jelölt algoritmusok létrehozásához és a hash kimenetek összevetéséhez. Ennek eredményeként a tervezők egyre jobbak a kollízióra kevésbé hajlamos algoritmusok létrehozásában.