Itt jársz most: Kezdőlap > Alkalmazásfejlesztés > Encoding, hashing, encryption - különbségek, használati céljaik

Szűrő megjelenítése

Encoding, hashing, encryption - különbségek, használati céljaik

A címben említett 3 műveletben az a közös, hogy minden esetben egy tetszőleges adat (például szöveg) vagy adatszerkezet átalakítását takarja egy másik formátumba. A célformátum tipikusan egyszerű szöveges vagy bináris adat, ami lehetővé teszi a forrásadat például hálózaton történő továbbítását vagy perzisztens tárolását. Abban viszont nagy különbségek vannak, hogy mikor lehet vagy épp kell őket használni, illetve hogy a forrásadat visszaállítható-e később. Nézzük őket egyenként.

Encoding

Az encoding a "legegyszerűbb" művelet a három közül, titkosítás nélküli adatformátum változtatást, tipikusan szerializálást takar. Encoding például az is, ha egy karaktert a belső reprezentációjára alakítunk (például ASCII, UTF-8), illetve a Base64 vagy URL encoding is, amiket tipikusan hálózaton történő adattovábbítás céljából használunk. Az encoding művelet invertálható, tehát a (belső) reprezentációból visszaállítható a forrásadat, ezt a műveletet hívjuk decoding-nak. Mivel az encoding műveletek nem titkosítják a forrásadatot, csupán egy reprezentációt készítenek belőle, használata nem ajánlott titkosítást igénylő adatok továbbítására, tárolására, így például jelszavakat, kulcsokat nem szabad csak encoded formában kezelni.

Base64

A Base64 egyébként egy sokrétű encoding technika, mivel bármilyen adatot is próbálunk encode-olni vele, a leképzett szöveg csak az angol ABC kis- és nagybetűit, számjegyeket, valamint a +, / és = jeleket fogja tartalmazni, utóbbit az úgynevezett "padding" céljából (ennek részleteibe nem mennék bele, akit mélyebben érdekel a téma, érdemes utánaolvasni). Base64 encodingot használ például az Authorization Basic header (a forrásadat a felhasználónév és a jelszó kettősponttal elválasztva, ami természetesen egyáltalán nem biztonságos, HTTP csatornán könnyedén lehallgatható, így már csak például a HTTPS-t megkövetelő OAuth specifikáció kliens azonosítására szokás használni a token csere közben), vagy leküldhetünk a böngészőnek képeket is Base64 encoded formában, amit az automatikusan tud decode-olni. Emellett persze sok más esetben is használhatunk Base64 encodingot, a lényeg amit észben kell viszont tartanunk, hogy a Base64 encoding nem titkosítás, érzékeny adatokat lehallgatható csatornán soha ne küldjünk át kizárólag Base64 encoded formában, használjunk helyette vagy mellette valamilyen titkosítást is.

Hashing

A hashing műveletek a forrásadat egyirányú, fix hosszúságú leképezését teszik lehetővé, tehát a forrásadatot egy olyan formátumba konvertálják, ami aztán biztonságosan átküldhető akár lehallgatható csatornán keresztül is, mivel a forrásadat nem állítható vissza a hashed formátumból. Felmerülhet persze a kérdés, hogy ez miért jó nekünk, hogyan lehet hasznos az, ha a forrásadat nem állítható vissza? Nos, hashelést tipikusan jelszavak tárolására használunk, mivel jelszavakat, adatbiztonsági okokból, soha nem szabad titkosítatlanul, illetve visszaállítható formátumban tárolni (képzeljük el azt, hogy az online banki jelszavunkat az email címünkkel, bankszámlaszámunkkal, és bármilyen egyéb azonosítónkkal együtt el tudja például egy adatbázis adminisztrátor olvasni, vagy hogy ugyanez az adatbázis egy "hacker-támadás" során kikerül az internetre). Szerencsére az ehhez hasonló biztonsági problémák ellen már egy bármilyen manapság ipari standardnak minősülő hashelési technika elégséges lehet.

Hashelés során meglehetősen bonyolult matematikai műveletek használatával a forrásadat egy olyan formátumba alakul, amelyet többé nem tudunk visszaállítani, de ha ugyanazt a forrásadatot újra hasheljük, a két hash "azonos" lesz. Bár ránézésre lehet nem ezt fogjuk látni, mivel bizonyos hashelési módszerek használnak úgynevezett "salt"-ot is (például a BCrypt), ami egy véletlenszerű érték, belekombinálva a forrásadatba. Az összehasonlítást ilyen esetekben a hashelő library által biztosított összehasonlító művelettel kell végezni, mivel az fel tudja ismerni a hashben levő salt értéket, és ugyanazzal fogja újrahashelni a kapott forrásadatot.

Bármilyen egyszerűnek és nyilvánvalónak tűnik mindez, sajnos számos olyan hashing technika van még mind a mai napig használatban, amit az ipar már nem tekint biztonságosnak. Ilyen például az MD5 és az SHA-1, amik önmagukban már könnyen törhetőek, és mivel a reprezentációjuk túl rövid, hosszabb forrásadatokból adatvesztés miatt akár ugyanaz a hash is generálódhat. Manapság az SHA-256, SHA-512 és BCrypt hashelés az ajánlott például jelszavak tárolására, bár fontos megjegyezni, hogy a BCrypt maximum 72 karakteres forrásadat kezelésére alkalmas, az afölötti karaktereket egyszerűen ignorálja az algoritmus.

Encryption

De mi történik akkor, ha a forrásadatokat nem egyszerűen csak tárolni szeretnénk titkosítva, de továbbítani és visszaállítani is? Itt jön képbe a harmadik művelet, az encryption. Encryptálás során újabb és még bonyolultabb matematikai műveletek eredményeképp egy olyan reprezentációt kapunk, amit egy kulcs segítségével visszaállíthatunk az eredeti formátumba (a műveletet decryption-nek hívjuk). A hasheléssel ellentétben itt bármilyen forrásadat méret limitáció adatvesztést okozna, így az encryption algoritmusok természetesen fel vannak készítve tetszőleges hosszúságú forrásadatok kezelésére.

Encryption technikák tekintetében megkülönböztetünk szimmetrikus-kulcsos és aszimmetrikus-kulcsos algoritmusokat. Előbbi esetben a feladó és a fogadó ugyanazzal a kulccsal kell rendelkezzen, míg utóbbi esetben egy publikus-privát kulcspár segítségével történik az adatok titkosítása és visszafejtése. Manapság népszerű szimmetrikus-kulcsos encryption algoritmus az AES, az aszimmetrikus módszerek között pedig az RSA az egyik legelterjedtebb, illetve az Ed25519 mint "trónbitorló" (ezutóbbi gyorsabb en-/decryptiont biztosít, kisebb kulcsok mellett, amik mégis nehezebben törhetőek, mint az RSA, bár inkább csak aláírásra ajánlott a használata).

Aszimmetrikus-kulcsos encryption

Szimmetrikus-kulcsok titkosítás esetén elég nyilvánvaló a helyzet, a feladó és a fogadó is megkapja ugyanazt a kulcsot, adatcsere során a feladó encryptálja az adatot, a fogadó decryptál, vége a történetnek. Aszimmetrikus titkosítás esetén ennél azonban kicsit bonyolultabb a dolog, ugyanis az is számít, milyen jellegű adatokat titkosítunk és milyen célból. Az RSA algoritmus például elég tipikus JWT tokenek aláírására. Az aláírás a token tartalma alapján történik, maga az aláírás biztosítja azt, hogy a token tartalma hiteles, az nem volt módosítva az aláírás után (mivel ebben az esetben az aláírás is megváltozna). A token aláírását, hogy hiteles legyen, kizárólag a tokent kiállító szerver teheti meg, így ő rendelkezik a privát kulccsal, az aláírási folyamat a token tartalmát és a privát kulcsot kombinálja az aláírássá. Később, amikor a kiállított tokennel egy azt igénylő szervert meghívunk, a szerver a privát kulcshoz tartozó publikus kulcs segítségével ellenőrzi az aláírást. Ha az sikeres, a token maga hiteles, a szerver feldolgozhatja a kérést. Ebben az esetben tehát a tokent kiállító (authorization) szerver jogosult a token kiállítására, így ő használja a privát kulcsot, mindenki más csak ellenőrzést kérhet a tokenre, ők használják a publikus kulcsot. Az RSA titkosítás HTTPS kommunikáció titkosításra is elterjedt, abban az esetben is ugyanez a felállás: a webszerver jogosult a HTTPS csomagok aláírására tehát nála van a privát kulcs, a böngésző csak ellenőrzést kérhet a csomagokra, tehát ő csak a publikus kulccsal rendelkezik.

Azonban, ha a feladó például egy szigorúan titkos dokumentumot szeretne valakinek elküldeni, az encryptionhöz a publikus kulcsot fogja használni, míg a fogadó a privát kulccsal decryptál. De miért, aláírást eddig a privát kulccsal végeztünk, publikussal csak ellenőriztünk, itt pedig most pont fordítva tesszük? Igen, pontosan, ez pedig arra vezethető vissza, hogy ki jogosult egy bizonyos művelet elvégzésére. A titkosított dokumentumot mikor a feladó elküldi, a publikus kulccsal biztosítja azt, hogy a dokumentum hiteles és jogosulatlan fél nem férhet hozzá, mivel ahhoz szükség van a privát kulcsra. De ebben az esetben ez nem csak egy aláírás, hanem maga a teljes dokumentum titkosítása. A jogosult fogadó fél viszont rendelkezik a privát kulccsal, tehát ő tudja azt decryptálni. Gondoljunk bele, ha ugyanúgy a privát kulccsal titkosítanánk, a szó szerint bárki által ismert publikus kulccsal decryptálnánk, akkor valójában bárki megnyithatná azt a szigorúan titkos dokumentumot. Hogy egy még egyszerűbb példával éljek, az email kliensek is ezzel módszerrel titkosítják az emaileket. Persze, ebből általában semmit nem látunk, mivel a kliensek egy viszonylag bonyolult "kézfogás" során kicserélik egymás között a kulcsaikat, aztán a kommunikáció köztük már a birtokolt aszimmetrikus kulcsokkal titkosítva folytatódik.

Összefoglalva tehát a három műveletet:

  • Az encoding csupán arra szolgál, hogy a forrásadatot "szállítható" formába konvertáljuk, de ez nem titkosít, és természetesen visszaállítható (decoding művelettel);
  • A hashelés tipikusan jelszavak tárolására használt, nem invertálható titkosítás;
  • Az encryption aláírásra és annak ellenőrzésére, illetve érzékeny adatok szállítás közbeni titkosítására szolgál, és visszaállítható (decryption művelettel).
Kommentek

Komment írásához jelentkezz be
Bejelentkezés

Még senki nem szólt hozzá ehhez a bejegyzéshez.