⏱️ Kriptografija ir RFC protokolai ✓ IETF standartų analizė

TOTP prieš HOTP: esminiai skirtumai, saugumas ir veikimo principai

Milijonai programuotojų ir saugumo inžinierių kasdien mato besikeičiančius 6 skaitmenų patvirtinimo kodus, tačiau nedaugelis supranta elegantišką matematinį mechanizmą, veikiantį ekrano gilumoje. Nuo RFC 4226 (HOTP) įvykiais valdomų skaitiklių 2005 m. iki RFC 6238 (TOTP) diskrečiųjų laiko žingsnių 2011 m. – šiame gide nagrinėjamas baitų lygio dinaminio trumpinimo (Dynamic Truncation) algoritmas, skaitiklių desinchronizavimo pažeidžiamumai, laikrodžio poslinkio tolerancija ir priežastys, kodėl TOTP užkariavo šiuolaikinį internetą.

2FA
2FA-Tool Saugumo komanda
Atnaujinta: 2026 m. spalis
Numatomas skaitymo laikas: 14 min. (2 600+ žodžių)
RFC 6238 RFC 4226 Dinaminis trumpinimas
💡 Kriptografinės išvados (TL;DR)
  • Esminis įvesties skirtumas: HOTP skaičiuoja maišos reikšmes iš monotoniškai didėjančio skaitiklio C, o TOTP skaitiklį C pakeičia epochos laiko žingsniu T (CurrentUnixTime / 30).
  • Tiesioginis paveldimumas: TOTP matematiškai yra HOTP specializacija: TOTP(K, Time) = HOTP(K, T). Abu algoritmai naudoja lygiai tą pačią dinaminio trumpinimo (Dynamic Truncation) funkciją.
  • Architektūrinis lemiamas veiksnys: HOTP reikalauja būsenos išsaugojimo (stateful) – serveriai privalo užrakinti ir atnaujinti skaitiklius duomenų bazėje po kiekvieno patvirtinimo. TOTP yra bebūsenis (stateless), todėl modernios debesijos mikropaslaugos gali tikrinti kodus paskirstytuose klasteriuose be centralizuotų duomenų bazės įrašymo operacijų.
01

Istorinės šaknys: nuo patentuotų aparatinės įrangos raktų iki atvirų žiniatinklio standartų

2000-ųjų pradžioje korporatyviniame dviejų veiksnių autentifikavime dominavo patentuoti aparatiniai raktai, tokie kaip „RSA SecurID“. Šiuose uždaruose, brangiuose įrenginiuose buvo įmontuoti vidiniai kvarco kristalai, sinchronizuoti su patentuotais įmonių serveriais. Jei organizacija norėjo suteikti kelių veiksnių saugumą tūkstančiams darbuotojų, įrangos pirkimo ir patentuotų licencijų kaštai buvo milžiniški.

Siekiant išlaisvinti autentifikavimą nuo patentuotų gamintojų monopolijos, pramonės lyderiai įkūrė OATH (Initiative for Open Authentication) konsorciumą, kurio tikslas buvo sukurti atvirus, nemokamus IETF standartus, kuriuos bet kuris programinės įrangos inžinierius galėtų laisvai nagrinėti, įgyvendinti ir audituoti:

📜 2005 m.: RFC 4226 (HOTP)

HMAC-Based One-Time Password Algorithm. Pritaikytas mažos galios mikrovaldikliams su fiziniu mygtuku. Paspaudus mygtuką, vidinis skaitiklis padidinamas ir LCD ekrane parodomas 6 skaitmenų kodas.

📜 2011 m.: RFC 6238 (TOTP)

Time-Based One-Time Password Algorithm. Sukurtas sparčiai plintant išmaniesiems telefonams. Naudodamas mobiliojo ryšio NTP tinklo laiko sinchronizaciją, TOTP visiškai panaikino fizinių mygtukų būsenų nesutapimus.

02

HOTP (RFC 4226) architektūra ir dinaminio trumpinimo baitų mechanizmas

Pagrindinė matematinė HOTP apibrėžtis yra stebėtinai glausta:

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

Parametrų paaiškinimas:

  • K: Bendrinamas simetrinis slaptasis raktas (paprastai iš Base32 iškoduota 160 bitų / 20 baitų dvejetainė seka).
  • C: 8 baitų (64 bitų) big-endian sveikasis skaitiklis.
  • HMAC-SHA-1: Raktu apsaugotas pranešimo autentifikavimo kodas, sukuriantis 20 baitų (160 bitų) kriptografinį maišos rezultatą (digest).

🔍 Kaip dinaminis trumpinimas (Dynamic Truncation) paverčia 20 baitų į 6 skaitmenis:

HMAC-SHA1 rezultatas susideda iš 160 bitų (20 baitų). Norint išgauti 6 tolygiai pasiskirsčiusius dešimtainius skaitmenis, reikalingas deterministinis, kolizijoms atsparus parinkimo mechanizmas, aprašytas RFC 4226 5.3 skyriuje:

// 1 žingsnis: Dinaminio poslinkio (Offset) apskaičiavimas
Offset = HS[19] & 0x0F
Paimamas paskutinis 20 baitų maišos rezultato baitas (indeksas 19). Kaukė su 0x0F išskiria žemesniuosius 4 bitus, duodama sveikąjį skaičių griežtai tarp 0 ir 15 (0x0 iki 0xF). Tai garantuoja, kad vėlesnis 4 baitų išrinkimas niekada neviršys 20 baitų buferio ribų (nes 15 + 4 = 19).
// 2 žingsnis: 4 nuoseklių baitų išrinkimas su kauke
P = ( (HS[Offset] & 0x7F) << 24 ) | ( (HS[Offset+1] & 0xFF) << 16 ) | ( (HS[Offset+2] & 0xFF) << 8 ) | ( HS[Offset+3] & 0xFF )
Išrenkami 4 baitai, prasidedantys ties Offset indeksu. Kaukė 0x7F nunulina vyriausiąjį bitą (MSB), kad būtų išvengta su ženklu susijusio sveikojo skaičiaus perpildymo skirtingose procesorių architektūrose (užtikrinant gryną teigiamą 31 bito sveikąjį skaičių).
// 3 žingsnis: Modulinė aritmetika galutiniams skaitmenims
OTP = P mod 106 = P mod 1000000
Pritaikius modulį 1 000 000, išskiriami galutiniai 6 dešimtainiai skaitmenys, prireikus papildant priekiniais nuliais (pvz., 748 tampa „000748“).
🧪 Konkretus testo vektorius iš RFC 4226 D priedo:

Tarkime, kad slaptasis raktas yra ASCII "12345678901234567890", o skaitiklis C = 0. Gautas HMAC-SHA1 maišos rezultatas šešioliktainiu formatu:

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

1. Paskutinis baitas yra 0x71. 0x71 & 0x0F = 0x01, todėl Offset = 1.
2. Baitai nuo 1 iki 4 yra: 93 cf 18 50. Nunulinus MSB gaunama 0x13cf1850, kas dešimtaine sistema yra 332,339,280.
3. 332339280 mod 1000000 = 339280. Galutinis 6 skaitmenų OTP kodas yra 339280!

03

TOTP (RFC 6238) evoliucija: laiko žingsnio magija

HOTP reikalavo nuolat sinchronizuoti kliento ir serverio skaitiklį. Programinės įrangos įrenginiuose mygtukų ar klavišų paspaudimų skaičiavimas neišvengiamai sukelia žmogiškąsias klaidas.

RFC 6238 skaitiklį C pakeitė diskrečiuoju laiko žingsniu T, išvestu tiesiogiai iš „Unix“ epochos laikrodžio:

T = ⌊ (CurrentUnixTime - T0) / X ⌋
  • CurrentUnixTime: sekundės, praėjusios nuo 1970-01-01 00:00:00 UTC.
  • T0: epochos atskaitos pradžia (visuose šiuolaikiniuose diegimuose lygi 0).
  • X (laiko žingsnio langas): standartinė rekomenduojama trukmė – 30 sekundžių.
  • Sveikosios dalies funkcija ⌊ ⌋: bet kuriai laiko žymai per 30 sekundžių langą T išlieka griežtai invariantinis. Pavyzdžiui, tarp epochos sekundžių 1728211200 ir 1728211229, T reikšmė yra visiškai tas pats 64 bitų sveikasis skaičius.

Dvejetainė serializacija: apskaičiavus T, jis supakuojamas į 8 baitų big-endian dvejetainį buferį (kurio atminties struktūra visiškai identiška skaitikliui C HOTP algoritme). Todėl bendra formulė tampa:
TOTP(K, Time) = HOTP(K, T) Ši matematinė elegancija paaiškina, kodėl autentifikavimo programėlės sinchroniškai atnaujina kodus kas 30 sekundžių, nereikalaudamos pastovaus būsenos sinchronizavimo tarp įrenginio ir serverio.

RFC 6238 SHA-256 ir SHA-512 palaikymas: Nors RFC 4226 griežtai apibrėžė tik HMAC-SHA-1, RFC 6238 išplėtė palaikymą HMAC-SHA-256 ir HMAC-SHA-512 algoritmams. SHA-256 (32 baitų maiša) atveju poslinkis imamas iš 31 baito (HS[31] & 0x0F); SHA-512 (64 baitų maiša) atveju poslinkis imamas iš 63 baito (HS[63] & 0x0F). Tačiau 99,9 % komercinių svetainių („Google“, „Microsoft“, „GitHub“, AWS) SHA-1 išlieka visuotiniu standartu dėl plataus suderinamumo su senesniais mobiliaisiais klientais.
04

Išsami palyginimo matrica (HOTP prieš TOTP)

Aspektas HOTP (RFC 4226) TOTP (RFC 6238)
Įvesties kintamasis Įvykių skaitiklis C (monotoniškai didėjantis) Laiko žingsnis T (30 sekundžių „Unix“ epochos langas)
Kodo galiojimo laikas Neterminuotas (galioja, kol bus panaudotas kitam prisijungimui) Griežtai 30 sekundžių (automatiškai nustoja galioti)
Serverio architektūra Būseninė (stateful – reikalauja atominių įrašų į DB kiekvieno prisijungimo metu) Bebūsenė (stateless – nepriklausomas NTP tikrinimas)
Pakartotinio panaudojimo (replay) rizika Vidutinė (perimtas kodas galioja iki faktinio panaudojimo) Minimali (apribota likusiomis dabartinio 30 sek. lango sekundėmis)
Pagrindinė gedimo priežastis Skaitiklio desinchronizacija (atsitiktiniai mygtuko paspaudimai) Laikrodžio poslinkis (kliento įrenginio laiko netikslumas)
Palaikomi maišos algoritmai Išskirtinai tik HMAC-SHA-1 HMAC-SHA-1, HMAC-SHA-256, HMAC-SHA-512
Pritaikymas pramonėje Senieji bankiniai raktai, specializuotos fizinės praėjimo sistemos 99,9 % šiuolaikinių žiniatinklio autentifikatorių
05

Desinchronizacija prieš laiko poslinkį: inžineriniai sprendimai

Paskirstytose gamybinėse sistemose klientų ir serverių parametrai neišvengiamai skiriasi. Kriptografai suprojektavo aiškius kompensavimo langus, užtikrinančius sistemos patikimumą:

⚙️ HOTP sprendimas: pažvelgimo į priekį langas (Look-Ahead Window, s)

Jei vartotojas 5 kartus paspaudžia generatoriaus mygtuką nepateikdamas kodo serveriui, kliento skaitiklis pasiekia C+5, o serveris lieka ties C.
RFC 4226 nurodo, kad autentifikavimo metu serveris apskaičiuoja ateities langą [C+1, C+s] (paprastai s=20). Jei randamas sutapimas, serveris peršoka į priekį ir nedelsdamas sinchronizuoja skaitiklį C.

⏱️ TOTP sprendimas: laiko poslinkio tolerancija (±1 langas)

Dėl tinklo delsos ar kliento įrenginio laikrodžio netikslumo (pvz., telefono laikrodis atsilieka 10 sekundžių), kodai gali atkeliauti gretimuose laiko žingsniuose.
Gamybiniai serveriai tikrina 3 langų masyvą: [T-1, T, T+1], faktiškai išplėsdami priėmimo intervalą iki 90 sekundžių.

Privaloma apsaugos nuo pakartojimo taisyklė: Kad būtų išvengta pakartotinio panaudojimo atakų per 90 sekundžių tolerancijos langą, serveriai privalo kaupti ir užrakinti panaudotus kodus atmintyje (pvz., „Redis“) 90 sekundžių, atmesdami pasikartojančius pateikimus.
🛡️ Pastovaus laiko eilučių palyginimas (apsauga nuo laiko atakų):

Kai serveriai tikrina, ar vartotojo pateiktas kodas atitinka apskaičiuotą kodą, įprastiniai eilučių lygybės patikrinimai (pvz., userOtp === serverOtp) nutraukiami ties pirmuoju nesutampančiu simboliu. Užpuolikas, matuodamas mikroskopinius tinklo atsakymo laikus, gali po vieną atkurti visus skaitmenis. Įmonių sistemų vidinė logika naudoja pastovaus laiko lygybės palyginimus (pvz., crypto.timingSafeEqual „Node.js“ aplinkoje), kad užkirstų kelią šoninio kanalo laiko analizei.

06

Kodėl TOTP nugalėjo šiuolaikiniame internete

Lemiama TOTP pergalė prieš HOTP visame internete buvo nulemta trijų esminių architektūrinių pranašumų:

☁️ Bebūsenis debesijos mastelio keitimas

Paskirstytose kelių regionų mikropaslaugose bet kuris serveris su NTP sinchronizuotu laikrodžiu gali patvirtinti TOTP kodus be užklausų ar įrašų fiksavimo centralizuotoje duomenų bazėje.

📱 Mobiliosios ekosistemos sinergija

Išmanieji telefonai nuolat kalibruoja savo sistemos laikrodžius per mobiliojo ryšio stotis ir GPS, pašalindami laikrodžio poslinkį be fizinės aparatinės įrangos priežiūros.

🛡️ Siauras 30 sekundžių atakos langas

HOTP kodai lieka galioti neribotą laiką, kol bus panaudoti. TOTP kodai nustoja galioti per 30 sekundžių, automatiškai neutralizuodami nutekintus žurnalus ir tinklo paketų perėmimą.

🧮 Grynas kliento pusės RFC 6238 variklis

Išbandykite realaus laiko TOTP skaičiavimus 2FA-Tool

Pamatykite, kaip jūsų Base32 slaptoji eilutė paverčiama dinaminiais 6 skaitmenų kodais per HMAC-SHA1 dinaminį trumpinimą. 100 % neprisijungus prie tinklo jūsų naršyklėje.

Atidaryti internetinį generatorių