Ez az oktatóanyag megtanítja Önnek, hogyan hozhat létre biztonságos kivonatokat a Python hashlib moduljának beépített funkcióival.
Hasznos lehet megérteni a kivonatolás jelentőségét és a biztonságos kivonatok programozott kiszámítását – még akkor is, ha nem dolgozik az alkalmazásbiztonsággal. De miért?
Nos, amikor Python-projekteken dolgozik, valószínűleg találkozni fog olyan esetekkel, amikor aggódik a jelszavak és más érzékeny információk adatbázisokban vagy forráskódfájlokban való tárolása miatt. Ilyen esetekben biztonságosabb, ha kényes információkon futtatja a kivonatolási algoritmust, és az információ helyett a hash-t tárolja.
Ebben az útmutatóban bemutatjuk, mi az a hash, és miben különbözik a titkosítástól. A biztonságos hash függvények tulajdonságait is áttekintjük. Ezután általános kivonatolási algoritmusokat használunk a Pythonban lévő egyszerű szöveg kivonatának kiszámításához. Ehhez a beépített hashlib modult fogjuk használni.
Mindehhez és még sok máshoz kezdjük!
Tartalomjegyzék
Mi az a kivonatolás?
A kivonatolási folyamat egy üzenet karakterláncot vesz fel, és egy rögzített hosszúságú kimenetet ad, amelyet hash-nek neveznek. Ez azt jelenti, hogy a kimeneti hash hossza egy adott kivonatolási algoritmushoz rögzített – függetlenül a bemenet hosszától. De miben különbözik a titkosítástól?
A titkosítás során az üzenetet vagy az egyszerű szöveget egy titkosítási algoritmussal titkosítják, amely titkosított kimenetet ad. Ezután lefuttathatjuk a visszafejtési algoritmust a titkosított kimeneten, hogy visszakapjuk az üzenetet.
A hashelés azonban másként működik. Most tanultuk meg, hogy a titkosítási folyamat megfordítható, mivel a titkosított üzenetről át lehet lépni a titkosítatlan üzenetre, és fordítva.
A titkosítással ellentétben a kivonatolás nem invertálható folyamat, ami azt jelenti, hogy nem tudunk a hash-től a bemeneti üzenetig eljutni.
A hash-függvények tulajdonságai
Nézzünk meg gyorsan néhány olyan tulajdonságot, amelyeknek a hash függvényeknek eleget kell tenniük:
- Determinisztikus: A hash függvények determinisztikusak. Egy m üzenet esetén m hash értéke mindig ugyanaz.
- Preimage Resistant: Már foglalkoztunk ezzel, amikor azt mondtuk, hogy a hash nem invertálható művelet. Az előkép ellenállás tulajdonsága azt állítja, hogy lehetetlen megtalálni az m üzenetet a kimeneti hash-ből.
- Ütközésálló: Nehéznek (vagy számításilag kivitelezhetetlennek) kell lennie két különböző m1 és m2 üzenetsor megtalálása úgy, hogy az m1 hashje egyenlő legyen az m2 hash-ével. Ezt a tulajdonságot ütközésállóságnak nevezzük.
- Második Preimage Resistant: Ez azt jelenti, hogy adott egy m1 üzenet és a megfelelő m2 hash, nem lehetséges olyan m2 üzenetet találni, amelynél hash(m1) = hash(m2).
Python hashlib modulja
A Python beépített hashlib modulja számos kivonatolási és üzenetkivonat-algoritmus megvalósítását biztosítja, beleértve az SHA és MD5 algoritmusokat.
A Python hashlib modul konstruktorainak és beépített függvényeinek használatához importálhatja azt a munkakörnyezetébe, így:
import hashlib
A hashlib modul biztosítja az algorithms_available és algorithms_guaranteed konstansokat, amelyek az algoritmusok azon halmazát jelölik, amelyek megvalósítása elérhető és garantált egy platformon.
Ezért az algoritmusok_garantált az algorithms_available részhalmaza.
Indítson el egy Python REPL-t, importálja a hashlib-et, és érje el az algorithms_available és algorithms_guaranteed konstansokat:
>>> hashlib.algorithms_available
# Output {'md5', 'md5-sha1', 'sha3_256', 'shake_128', 'sha384', 'sha512_256', 'sha512', 'md4', 'shake_256', 'whirlpool', 'sha1', 'sha3_512', 'sha3_384', 'sha256', 'ripemd160', 'mdc2', 'sha512_224', 'blake2s', 'blake2b', 'sha3_224', 'sm3', 'sha224'}
>>> hashlib.algorithms_guaranteed
# Output {'md5', 'shake_256', 'sha3_256', 'shake_128', 'blake2b', 'sha3_224', 'sha3_384', 'sha384', 'sha256', 'sha1', 'sha3_512', 'sha512', 'blake2s', 'sha224'}
Látjuk, hogy az algoritmusok_garantált valóban az algorithms_available részhalmaza
Hogyan lehet Hash objektumokat létrehozni Pythonban
Ezután tanuljuk meg, hogyan hozhat létre hash objektumokat Pythonban. Kiszámítjuk egy üzenetkarakterlánc SHA256 hash értékét a következő módszerekkel:
- Az általános new() konstruktor
- Algoritmus-specifikus konstruktorok
A new() konstruktor használatával
Inicializáljuk az üzenetet:
>>> message = "etoppc.com is awesome!"
A hash objektum példányosításához használhatjuk a new() konstruktort, és átadhatjuk az algoritmus nevét, amint látható:
>>> sha256_hash = hashlib.new("SHA256")
Most már meghívhatjuk az update() metódust a hash objektumon az üzenet karakterlánccal argumentumként:
>>> sha256_hash.update(message)
Ha így tesz, hibába ütközik, mivel a kivonatoló algoritmusok csak bájtkarakterláncokkal működnek.
Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Unicode-objects must be encoded before hashing
A kódolt karakterlánc beszerzéséhez hívja meg az encode() metódust a metódusban, majd használja az update() metódushívásban. Ezt követően meghívhatja a hexdigest() metódust, hogy megkapja az üzenet karakterláncának megfelelő sha256 hash-t.
sha256_hash.update(message.encode()) sha256_hash.hexdigest() # Output:'b360c77de704ad8f02af963d7da9b3bb4e0da6b81fceb4c1b36723e9d6d9de3d'
Ahelyett, hogy az üzenetet az encode() metódussal kódolná, bájtok karakterláncaként is megadhatja, ha a karakterláncot b előtaggal rögzíti, így:
message = b"etoppc.com is awesome!" sha256_hash.update(message) sha256_hash.hexdigest() # Output: 'b360c77de704ad8f02af963d7da9b3bb4e0da6b81fceb4c1b36723e9d6d9de3d'
A kapott hash ugyanaz, mint az előző hash, ami megerősíti a hash függvények determinisztikus jellegét.
Ezen túlmenően, egy kis változtatás az üzenetkarakterláncban a hash drasztikus változását okozhatja (más néven „lavinaeffektus”).
Ennek ellenőrzésére változtassuk az „a”-t az „awesome”-ban „A”-ra, és számítsuk ki a hash-t:
message = "etoppc.com is Awesome!" h1 = hashlib.new("SHA256") h1.update(message.encode()) h1.hexdigest() # Output: '3c67f334cc598912dc66464f77acb71d88cfd6c8cba8e64a7b749d093c1a53ab'
Látjuk, hogy a hash teljesen megváltozik.
Az algoritmus-specifikus konstruktor használata
Az előző példában az általános new() konstruktort használtuk, és az „SHA256”-ot adtuk meg az algoritmus neveként a hash objektum létrehozásához.
Ehelyett használhatjuk az sha256() konstruktort is, ahogy az ábra mutatja:
sha256_hash = hashlib.sha256() message= "etoppc.com is awesome!" sha256_hash.update(message.encode()) sha256_hash.hexdigest() # Output: 'b360c77de704ad8f02af963d7da9b3bb4e0da6b81fceb4c1b36723e9d6d9de3d'
A kimeneti hash megegyezik azzal a hashvel, amelyet korábban a „etoppc.com is awesome!” üzenethez kaptunk.
A hash-objektumok attribútumainak feltárása
A hash objektumok néhány hasznos tulajdonsággal rendelkeznek:
- Az digest_size attribútum a kivonat méretét jelöli bájtokban. Például az SHA256 algoritmus 256 bites hash-t ad vissza, ami 32 bájtnak felel meg.
- A block_size attribútum a kivonatolási algoritmusban használt blokkméretre vonatkozik.
- A name attribútum annak az algoritmusnak a neve, amelyet a new() konstruktorban használhatunk. Az attribútum értékének megkeresése hasznos lehet, ha a hash objektumoknak nincs leíró neve.
Ezeket az attribútumokat ellenőrizhetjük a korábban létrehozott sha256_hash objektumhoz:
>>> sha256_hash.digest_size 32 >>> sha256_hash.block_size 64 >>> sha256_hash.name 'sha256'
Ezután nézzünk meg néhány érdekes hash-alkalmazást a Python hashlib moduljával.
Gyakorlati példák a kivonatolásra
Szoftverek és fájlok integritásának ellenőrzése
Fejlesztőként folyamatosan letöltünk és telepítünk szoftvercsomagokat. Ez attól függetlenül igaz, hogy Linux disztribúción, Windowson vagy Macen dolgozik.
Előfordulhat azonban, hogy a szoftvercsomagokhoz tartozó egyes tükrök nem megbízhatóak. A hash (vagy ellenőrző összeg) a letöltési link mellett található. A letöltött szoftver integritását pedig úgy ellenőrizheti, hogy kiszámítja a hash-t, és összehasonlítja a hivatalos hash-sel.
Ez a gépén lévő fájlokra is alkalmazható. Még a legkisebb változtatás is a fájl tartalmában drasztikusan megváltoztatja a hash-t, a hash ellenőrzésével ellenőrizheti, hogy a fájl módosult-e.
Íme egy egyszerű példa. Hozzon létre egy „sajat_fájl.txt” szövegfájlt a munkakönyvtárban, és adjon hozzá tartalmat.
$ cat my_file.txt This is a sample text file. We are going to compute the SHA256 hash of this text file and also check if the file has been modified by recomputing the hash.
Ezután megnyithatja a fájlt olvasási bináris módban (‘rb’), beolvashatja a fájl tartalmát, és kiszámíthatja az SHA256 hash-t a képen látható módon:
>>> import hashlib >>> with open("my_file.txt","rb") as file: ... file_contents = file.read() ... sha256_hash = hashlib.sha256() ... sha256_hash.update(file_contents) ... original_hash = sha256_hash.hexdigest()
Itt az original_hash változó a ‘my_file.txt’ kivonata jelenlegi állapotában.
>>> original_hash # Output: '53bfd0551dc06c4515069d1f0dc715d002d451c8799add29f3e5b7328fda9f8f'
Most módosítsa a ‘my_file.txt’ fájlt. Eltávolíthatja az extra szóközt a „megy” szó előtt. 🙂
Számítsa ki még egyszer a hash-t, és tárolja a computed_hash változóban.
>>> import hashlib >>> with open("my_file.txt","rb") as file: ... file_contents = file.read() ... sha256_hash = hashlib.sha256() ... sha256_hash.update(file_contents) ... computed_hash = sha256_hash.hexdigest()
Ezután hozzáadhat egy egyszerű assert utasítást, amely azt állítja, hogy a computed_hash egyenlő az eredeti_kivonattal.
>>> assert computed_hash == original_hash
Ha a fájl módosul (ez ebben az esetben igaz), AssertionError üzenetet kell kapnia:
Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError
A kivonatolást kényes adatok, például jelszavak adatbázisokban való tárolásakor használhatja. Adatbázisokhoz való csatlakozáskor a jelszó-hitelesítés során is használhatja a hash-t. Érvényesítse a bevitt jelszó kivonatát a helyes jelszó kivonatával.
Következtetés
Remélem, ez az oktatóanyag segített megtanulni a biztonságos kivonatok létrehozását a Python segítségével. Íme a legfontosabb tudnivalók:
- A Python hashlib modulja számos kivonatolási algoritmus használatra kész megvalósítását biztosítja. A platformján garantált algoritmusok listáját a hashlib.algorithms_guaranteed segítségével érheti el.
- Hash objektum létrehozásához használhatja az általános new() konstruktort a következő szintaxissal: hashlib.new(“algo-name”). Alternatív megoldásként használhatja az adott kivonatolási algoritmusoknak megfelelő konstruktorokat, például: hashlib.sha256() az SHA 256 hash-hez.
- A kivonatolni kívánt üzenetkarakterlánc és a hash objektum inicializálása után meghívhatja az update() metódust a hash objektumon, majd a hexdigest() metódust a hash lekéréséhez.
- A kivonatolás hasznos lehet a szoftveres műtermékek és fájlok integritásának ellenőrzésekor, érzékeny információk adatbázisokban való tárolásakor stb.
Ezután tanulja meg, hogyan kell kódolni egy véletlenszerű jelszógenerátort Pythonban.