Alapozás
Azt hiszem, nem árulok el nagy titkot, ha azt mondom, körülbelül az utolsó két évtizedben az informatika robbanásszerű fejlődésnek indult, ezzel együtt egyre több és több szolgáltatás épül rá (gondoljunk csak a használható streaming szolgáltatásokra, felhőkre, online fizetési megoldásokra). Mivel egyre többen férnek hozzá a technikai fejlődés vívmányaihoz, minden eddiginél fontosabbá vált a különböző érzékeny adatok védelme. Ez természetesen azt jelenti - a technikai fejlődéssel egyetemben -, hogy a védelemnek is fejlődnie kell. Egyre szélesebb körű és egyre több rétegből álló védelmet kell felállítanunk ahhoz, hogy a fontos információk ne kerülhessenek illetéktelen kezekbe.
Ennek a védelemnek az egyik legrégibb eleme a biztonságos jelszó - megragadnám az alkalmat, hogy azonnal tisztázzam is, mire gondolok, mert a fenti kijelentés eléggé kétértelmű. Nos, mindkettőre gondolok:
- a jelenlegi kutatások szerint a minimális biztonságos jelszóhossz 12 karakter, kisbetűkből, nagybetűkből és számokból áll. Fontos különbség a korábbiakhoz képest, hogy újabban a speciális karaktereket nem tartják fontosnak a kutatók - és azt is érdemes megjegyezni, hogy sok webes szolgáltatás nem is támogatja ezek használatát
- a másik fontos szempont, hogy biztonságos algoritmus generálja a jelszavakat.
Hirdetés
Mit takar ez utóbbi kitétel? Jelszavakat sokféle módon lehet generálni, de minden biztonsági rendszer az IT-ban kriptográfiára épül. Nos, a biztonságos algoritmus olyan kriptográfiai elemekre épül, ahol az algoritmus kimenete nem jósolható meg előre. A jelszó generálás olyan terület, ahol fontos ez a kitétel, így nem mindegy, milyen eszközöket használunk.
A művelet alapja, hogy a kiválasztott karakterek véletlenszerűen kerüljenek a jelszóba. És itt komoly problémába ütközünk: az igazi véletlenszerűséghez valamilyen állandóan változó környezeti állapotot használó hardveres generátor kell, ami drága, egyébként be kell érnünk a sokkal gyengébb pszeudo-generátorral, ahol véletlenszerűnek tűnik a generálás, viszont a generátor állapotának ismeretében a kimenet kiszámítható. Nincs azonban veszve minden, biztonsági szempontból megkülönböztethetünk pszeudo-generátorokat és kriptográfiailag biztonságos pszeudo-generátorokat.
Nos, jelszavak generálásához kizárólag az utóbbi csoport jöhet szóba.
Tegyük fel, hogy saját magunk szórakoztatására némi programozási gyakorlatot végzünk és jelszavakat szeretnénk generálni - mutatok egy rossz és egy jó megoldást is Pythonban.
A Cloudflare lávalámpákból álló fala, amit véletlenszám-generáláshoz használnak. Forrás: https://blog.cloudflare.com
Egy megoldás
Időnként bele-belekontárkodom Python programozásba, kisebb magán projekteket csináltam eddig, saját portscannert (programozási gyakorlatként az nmap modul nélkül), network discovery-t, ngSIEM rendszerek tesztelésére használható eszközöket (cryptor, keylogger stb.) és próbaképpen jelszó generátort.
Utóbbinál merült fel a gondolat: biztos, hogy a Python random modulja elég random? Nos, lássuk!
A Google kereső első 4 találata a "password generator python" keresőkifejezésre tulajdonképpen ugyanazt a megoldást adja apró implementációs különbségekről eltekintve, nagyon hasonlók az alábbi kódhoz:
import string
import random
uCC = string.ascii_uppercase
lCC = string.ascii_lowercase
num = string.digits
all = uCC + lCC + num
password = ''
for i in range(12):
password += random.choice(all)
print(password)
A fenti pár sor tényleg csak demonstrációs célokat szolgál - többek között demonstrálja, hogyan ne generáljunk jelszavakat.
A Python random modulja ugyanis kriptográfiailag nem biztonságos, az általa generált véletlenszerű számok előre megjósolhatók. Maxim Kochukov írt egy Python modult ennek bizonyítására randcrack néven. Mindössze 624 darab 32 bites szám generálása után a randcrack képes az ún. Mersenne Twister mátrix állapotának felismerésére, ezáltal teljesen szinkronba kerül a random modullal. Ha ekkor generáltatunk "véletlenszerű" számokat, mind a random, mind a randcrack ugyanazokat a kimeneteket adja. Megjegyzés: Maxim szerint a randcrack pontossága 50K szám generálása esetén csökken 50% környékére, 10K körül még 95%.
Teszt kód:
import random, time
from randcrack import RandCrack
random.seed(time.time())
rc = RandCrack()
for i in range(624):
rc.submit(random.getrandbits(32))
# Could be filled with random.randint(0,4294967294) or random.randrange(0,4294967294)
print("Random result: {}\nCracker result: {}"
.format(random.randrange(0, 4294967295), rc.predict_randrange(0, 4294967295)))
Egy másik megoldás
Fentiekből elég könnyen leszűrhető, hogy a Python random modulja nem alkalmas jelszavak generálására. Lássunk egy jobb, kriptográfiailag biztonságos megoldást.
import string
import secrets
uCC = string.ascii_uppercase
lCC = string.ascii_lowercase
num = string.digits
all = uCC + lCC + num
password = ''
for i in range(12):
password += secrets.choice(all)
print(password)
A Python secrets modulja az operációs rendszer által használt véletlenszám generátorokra alapul - jelen ismereteink szerint ezek megfelelően biztonságosak ahhoz, hogy a különböző védelmi megoldásokban, például jelszó generátorokban használhassuk.
A fentiek alapján ha netán nem tudunk időben félreugrani a hasonló feladatok elől, érdemes pro és kontra kutatásokat végezni, mielőtt egy implementációt az asztalra tennénk.
Miért nem a CoreInfinity.Tech blogon van az írás?
Sokan talán meglepetéssel veszik észre, hogy ide készült az írás a hazai pálya helyett. Nos, az indoklás elég egyszerű: ez egy technikai cikk, a CoreInfinity.Tech blogot pedig szeretném megtartani a magasabb szintű írások helyszíneként.