⏱️ Kriptográfia és RFC-protokollok ✓ Hivatalos IETF-szabványok elemzése

A TOTP és a HOTP összehasonlítása: Alapvető különbségek, biztonság és működési elvek

Fejlesztők és biztonsági mérnökök milliói találkoznak naponta a forgó 6 számjegyű ellenőrző kódokkal, ám kevesen értik a képernyő mögött működő elegáns matematikai mechanizmust. A 2005-ös, eseményvezérelt számlálókon alapuló RFC 4226 (HOTP) szabványtól a 2011-es, diszkrét időlépésekre épülő RFC 6238 (TOTP) szabványig ez az útmutató bájt szinten elemzi a dinamikus csonkítás (Dynamic Truncation) algoritmusát, a számláló deszinkronizációs sebezhetőségeit, az óraeltérés-toleranciát, valamint azt, hogy miért a TOTP hódította meg a modern webet.

2FA
2FA-Tool Biztonsági Mérnökcsapat
Frissítve: 2026. október
Becsült olvasási idő: 14 perc (több mint 2600 szó)
RFC 6238 RFC 4226 Dynamic Truncation
💡 Kriptográfiai összefoglaló (TL;DR)
  • Az alapvető bemeneti különbség: A HOTP a kivonatokat egy monoton növekvő C számlálóból számítja ki, míg a TOTP ezt a számlálót egy időlépésre cseréli: T = (CurrentUnixTime / 30).
  • Közvetlen öröklődés: A TOTP matematikailag a HOTP specializációja: TOTP(K, Time) = HOTP(K, T). Mindkét algoritmus pontosan ugyanazt a dinamikus csonkítási (Dynamic Truncation) függvényt alkalmazza.
  • Döntő architekturális tényező: A HOTP állapottartó (stateful – a szervereknek minden hitelesítéskor zárolniuk kell és lemezre kell menteniük a számlálót). A TOTP állapotmentes (stateless), lehetővé téve a modern felhős mikroszolgáltatások számára a tokenek terheléselosztott fürtökön keresztüli érvényesítését központi adatbázis-írási műveletek nélkül.
01

Történelmi gyökerek: A zárt hardvertokenektől a nyílt webszabványokig

A 2000-es évek elején a vállalati kétlépcsős azonosítás világát az olyan zárt forráskódú, drága hardvertokenek uralták, mint az RSA SecurID. Ezek a zárt eszközök belső kvarckristályokat tartalmaztak, amelyeket a vállalat dedikált szervereihez szinkronizáltak. Ha egy szervezet több ezer alkalmazott számára kívánt többfaktoros védelmet biztosítani, a hardverbeszerzés és a licencelés költségei rendkívül magasak voltak.

A hitelesítés zárt rendszerektől való függetlenítése érdekében az iparág vezető szereplői létrehozták az OATH (Initiative for Open Authentication) konzorciumot azzal a céllal, hogy nyílt, jogdíjmentes IETF-szabványokat fejlesszenek ki, amelyeket bármely szoftvermérnök szabadon megvizsgálhat, implementálhat és auditálhat:

📜 2005: RFC 4226 (HOTP)

HMAC-alapú egyszer használatos jelszó algoritmus (HMAC-Based One-Time Password Algorithm). Alacsony fogyasztású, fizikai gombbal ellátott mikrokontrollerekhez tervezték. A gomb megnyomása megnöveli a belső számlálót, és egy 6 számjegyű tokent jelenít meg az LCD-kijelzőn.

📜 2011: RFC 6238 (TOTP)

Időalapú egyszer használatos jelszó algoritmus (Time-Based One-Time Password Algorithm). Az okostelefonok térnyerésével párhuzamosan fejlesztették ki. A mobilhálózati NTP időszerver-szinkronizáció révén a TOTP teljesen megszüntette a fizikai gombnyomásokból fakadó számláló-eltéréseket.

02

A HOTP (RFC 4226) architektúrája és a Dynamic Truncation bájtmechanikája

A HOTP alapvető matematikai definíciója meglepően tömör és elegáns:

HOTP(K, C) = Truncate(HMAC-SHA-1(K, C)) mod 10DigitCount

A paraméterek részletezése:

  • K: Megosztott szimmetrikus titkos kulcs (jellemzően egy Base32-ből dekódolt 160 bites / 20 bájtos bináris sorozat).
  • C: 8 bájtos (64 bites) Big-Endian egész szám számláló.
  • HMAC-SHA-1: Kulcsalapú üzenethitelesítő kód, amely 20 bájtos (160 bites) kriptográfiai kivonatot hoz létre.

🔍 Hogyan alakít át a dinamikus csonkítás (Dynamic Truncation - DT) 20 bájtot 6 számjeggyé:

Az HMAC-SHA1 kivonat 160 bitből (20 bájtból) áll. A 6 egyenletes eloszlású decimális számjegy kinyeréséhez egy determinisztikus, ütközésbiztos kiválasztási mechanizmus szükséges, amelyet az RFC 4226 szabvány 5.3 szakasza rögzít:

// 1. lépés: Dinamikus eltolás (Dynamic Offset) kiszámítása
Offset = HS[19] & 0x0F
Vesszük a 20 bájtos kivonat legutolsó bájtját (a 19-es indexűt). A 0x0F értékkel végzett maszkolás izolálja az alsó 4 bitet, ami egy szigorúan 0 és 15 közötti egész számot ad (0x0-tól 0xF-ig). Ez biztosítja, hogy az ezt követő 4 bájt kinyerése soha ne lépje túl a 20 bájtos puffert (mivel 15 + 4 = 19).
// 2. lépés: 4 egymást követő bájt kinyerése maszkolással
P = ( (HS[Offset] & 0x7F) << 24 ) | ( (HS[Offset+1] & 0xFF) << 16 ) | ( (HS[Offset+2] & 0xFF) << 8 ) | ( HS[Offset+3] & 0xFF )
Kinyerünk 4 bájtot az Offset indextől kezdve. A 0x7F maszk lenullázza a legfelső helyiértékű bitet (MSB), hogy elkerülje az előjeles egész túlcsordulását a különböző CPU-architektúrákon (így tiszta pozitív 31 bites egészet garantál).
// 3. lépés: Moduló aritmetika a végső számjegyekhez
OTP = P mod 106 = P mod 1000000
Az 1 000 000-val végzett moduló művelet kiválasztja az utolsó 6 decimális számjegyet, szükség esetén vezető nullákkal kiegészítve (például a 748-ból "000748" lesz).
🧪 Konkrét tesztvektor az RFC 4226 D függelékéből:

Tegyük fel, hogy a titkos kulcs ASCII szövege: "12345678901234567890", a számláló értéke pedig C = 0. A keletkező HMAC-SHA1 kivonat hexadecimális formában:

cc 93 cf 18 50 8d 94 93 4c 64 b6 6d 8b fb 87 fb 23 cb 4b 71

1. Az utolsó bájt: 0x71. Mivel 0x71 & 0x0F = 0x01, ezért Offset = 1.
2. Az 1-től 4-ig terjedő bájtok: 93 cf 18 50. Az MSB lenullázása után 0x13cf1850-et kapunk, ami decimálisan: 332 339 280.
3. 332339280 mod 1000000 = 339280. A kapott 6 számjegyű OTP kód: 339280!

03

A TOTP (RFC 6238) fejlődése: Az időlépések logikája

A HOTP megkövetelte, hogy a kliens és a szerver számlálója szigorúan szinkronban maradjon. Szoftveres eszközökön a billentyűleütések vagy az alkalmazás megnyitásainak számlálása állandó emberi hibalehetőséget teremt.

Az RFC 6238 szabvány a C számlálót egy közvetlenül a Unix-időből származtatott diszkrét T időlépésre cserélte:

T = ⌊ (CurrentUnixTime - T0) / X ⌋
  • CurrentUnixTime: Az 1970-01-01 00:00:00 UTC óta eltelt másodpercek száma.
  • T0: A kezdeti időviszonyítási pont (minden modern rendszerben alapértelmezetten 0).
  • X (időlépés ablaka): A szabványos ajánlott időtartam: 30 másodperc.
  • Alsó egészrész függvény ⌊ ⌋: Bármely, a 30 másodperces időablakba eső időbélyeg esetén T értéke szigorúan változatlan marad. Például az 1728211200 és az 1728211229 másodpercek között a T pontosan ugyanazt a 64 bites egész számot adja eredményül.

Bináris szerializáció: Miután a T értékét kiszámítottuk, azt egy 8 bájtos Big-Endian bináris pufferbe csomagoljuk (amely memóriaszerkezetét tekintve teljesen megegyezik a HOTP C számlálójával). Ebből adódóan az egyesített képlet rendkívül elegánsan egyszerűsödik:
TOTP(K, Time) = HOTP(K, T) Ez a matematikai elegancia magyarázza, miért tudnak a hitelesítő alkalmazások szinkronban, 30 másodpercenként új kódokat generálni anélkül, hogy perzisztens hálózati állapotszinkronizációra lenne szükségük.

Az SHA-256 és SHA-512 támogatása az RFC 6238-ban: Míg az RFC 4226 kizárólag az HMAC-SHA-1-et definiálta, az RFC 6238 kiterjesztette a támogatást az HMAC-SHA-256 és HMAC-SHA-512 algoritmusokra is. Az SHA-256 (32 bájtos kivonat) esetén az eltolást a 31. bájtból vesszük (HS[31] & 0x0F); az SHA-512 (64 bájtos kivonat) esetén a 63. bájtból (HS[63] & 0x0F). Ennek ellenére a kereskedelmi webhelyek 99,9%-ánál (Google, Microsoft, GitHub, AWS) az SHA-1 maradt az általános alapértelmezés a régebbi mobilkliensekkel való kompatibilitás miatt.
04

Részletes összehasonlító mátrix (HOTP vs. TOTP)

Dimenzió HOTP (RFC 4226) TOTP (RFC 6238)
Bemeneti változó Eseményszámláló C (monoton növekvő) Időlépés T (30 másodperces Unix-időablak)
Token élettartama Határozatlan (érvényes a következő bejelentkezésig) Szigorúan 30 másodperc (automatikusan lejár)
Szerverarchitektúra Állapottartó (atomos adatbázis-írás minden belépéskor) Állapotmentes (független NTP időszerver-ellenőrzés)
Visszajátszásos támadásnak való kitettség Közepes (a lehallgatott kód érvényes marad felhasználásig) Minimális (csak az aktuális ablakból hátralévő másodpercekig)
Elsődleges hibaforrás Számláló-deszinkronizáció (véletlen gombnyomások) Óraeltérés (a kliens telefon órájának elcsúszása)
Támogatott kriptográfiai hash-ek Kizárólag HMAC-SHA-1 HMAC-SHA-1, HMAC-SHA-256, HMAC-SHA-512
Ipari elterjedtség Régebbi banki tokenek, speciális fizikai beléptetők A modern webes hitelesítők 99,9%-a
05

Deszinkronizáció vs. óraeltérés: Műszaki védelmi intézkedések

Elosztott éles rendszerekben a kliensek és a szerverek órái elkerülhetetlenül eltérhetnek egymástól. A kriptográfusok explicit kompenzációs ablakokat vezettek be a megbízhatóság garantálására:

⚙️ HOTP kompenzáció: Előretekintő ellenőrzési ablak (Look-Ahead Window s)

Ha a felhasználó 5-ször megnyomja a token gombját anélkül, hogy bejelentkezne, a kliens számlálója eléri a C+5 értéket, míg a szerver C állapotban marad.
Az RFC 4226 meghatározza, hogy a hitelesítés során a szerver egy [C+1, C+s] tartományra terjedő előretekintő ablakot számít ki (jellemzően s=20). Ha egyezést talál, a szerver azonnal előreugrik, és azonnal újraszinkronizálja a C számlálót.

⏱️ TOTP kompenzáció: Óraeltérés-tolerancia (±1 időablak)

A hálózati késleltetés vagy a klienseszköz órájának elcsúszása miatt (például ha a telefon órája 10 másodpercet késik) a tokenek a szomszédos időlépésekben érkezhetnek meg.
A szerverek 3 időlépésből álló tömböt értékelnek ki: [T-1, T, T+1], ami az elfogadási ablakot ténylegesen 90 másodpercre terjeszti ki.

Kötelező visszajátszás elleni szabály (Anti-Replay Rule): A 90 másodperces ablakon belüli visszajátszásos támadások elkerülése érdekében a szervereknek a felhasznált tokeneket gyors memóriatárban (például Redis) kell zárolniuk 90 másodpercig, elutasítva a duplikált beküldéseket.
🛡️ Állandó idejű karakterlánc-összehasonlítás (Időzítéses támadások elleni védelem):

Amikor a szerver ellenőrzi, hogy a felhasználó által megadott kód megegyezik-e a számított kóddal, az egyszerű karakterlánc-összehasonlítás (például userOtp === serverOtp) az első nem egyező karakternél megszakad. Egy támadó, aki mikroszkopikus hálózati válaszidőket mér, számjegyről számjegyre képes lehet rekonstruálni a kódot. A vállalati háttérrendszerek állandó idejű egyenlőségvizsgálatot írnak elő (például Node.js-ben a crypto.timingSafeEqual függvényt) az oldalcsatornás időzítéses elemzések meghiúsítására.

06

Miért nyert a TOTP a modern interneten?

A TOTP elsöprő győzelmét a HOTP felett a modern weben három alapvető mérnöki előny hajtotta:

☁️ Állapotmentes felhős skálázhatóság

Az elosztott, több régióban futó mikroszolgáltatásokban bármely, NTP-vel szinkronizált órájú szerverpéldány képes a TOTP tokenek ellenőrzésére központi adatbázis lekérdezése vagy zárolása nélkül.

📱 Sinergia a mobil ökoszisztémával

Az okostelefonok bázisállomások és GPS segítségével folyamatosan kalibrálják rendszerórájukat, így elhárítják az óraeltérés problémáit anélkül, hogy hardveres karbantartást igényelnének.

🛡️ Szűk, 30 másodperces támadási ablak

A HOTP tokenek a felhasználásig érvényben maradnak. A TOTP tokenek ezzel szemben 30 másodperc után lejárnak, automatikusan semlegesítve a kompromittált naplófájlokból vagy csomaglehallgatásból eredő kockázatokat.

🧮 Teljesen kliensoldali RFC 6238 motor

Tapasztalja meg a valós idejű TOTP számításokat a 2FA-Tool segítségével

Nézze meg, hogyan alakul át a Base32 titkos kulcs dinamikus 6 számjegyű kódokká az HMAC-SHA1 dinamikus csonkítás révén. 100%-ban offline a böngészőjében.

Online generátor megnyitása