⏱️ Kryptografia & RFC-protokollat ✓ IETF-standardien analyysi

TOTP vs HOTP selitettynä: Tärkeimmät erot, tietoturva ja toimintaperiaatteet

Miljoonat kehittäjät ja tietoturva-asiantuntijat katsovat vaihtuvia 6-numeroisia vahvistuskoodeja päivittäin, mutta harva ymmärtää niiden taustalla toimivaa eleganttia matemaattista koneistoa. Vuoden 2005 tapahtumapohjaisista RFC 4226 (HOTP) -laskureista vuoden 2011 diskreetteihin RFC 6238 (TOTP) -aikajaksoihin tämä opas analysoi tavutason Dynamic Truncation -algoritmia, laskurin desynkronointihaavoittuvuuksia, kellopoikkeaman toleransseja ja syitä sille, miksi TOTP valloitti modernin verkon.

2FA
2FA-Tool-tietoturvatiimi
Päivitetty lokakuussa 2026
Arvioitu lukuaika: 14 min (2 600+ sanaa)
RFC 6238 RFC 4226 Dynamic Truncation
💡 Kryptografiset pääkohdat (TL;DR)
  • Perustavanlaatuinen syöte-ero: HOTP laskee tiivisteet monotonisesti kasvavasta laskurista C, kun taas TOTP korvaa C:n epookkiaikajaksolla T (CurrentUnixTime / 30).
  • Suora perintä: TOTP on matemaattisesti HOTP:n erikoistapaus: TOTP(K, Time) = HOTP(K, T). Molemmat algoritmit hyödyntävät täsmälleen samaa Dynamic Truncation -funktiota.
  • Arkkitehtuurin ratkaiseva tekijä: HOTP on tilallinen (palvelinten on lukittava ja tallennettava laskurit levylle jokaisen vahvistuksen yhteydessä). TOTP on tilaton, mikä mahdollistaa nykyaikaisten pilvimikropalvelujen vahvistaa tokeneita hajautetuissa kuormantasausklustereissa ilman keskitettyjä tietokantakirjoituksia.
01

Historialliset juuret: Suljetuista laitetokeneista avoimiin verkkostandardeihin

2000-luvun alussa yritysten kaksivaiheista tunnistautumista hallitsivat suljetut laiteavaimet, kuten RSA SecurID. Nämä kalliit ja suljetut laitteet sisälsivät sisäisiä kvartsikiteitä, jotka oli synkronoitu valmistajakohtaisiin yrityspalvelimiin. Jos organisaatio halusi tarjota monivaiheisen suojauksen tuhansille työntekijöille, laitehankinnat ja lisenssikustannukset olivat kohtuuttoman korkeita.

Tunnistautumisen vapauttamiseksi suljetuista toimittajista alan johtavat toimijat perustivat OATH (Initiative for Open Authentication) -konsortion luomaan avoimia, rojaltivapaita IETF-standardeja, joita kuka tahansa ohjelmistokehittäjä voi vapaasti tarkastella, toteuttaa ja auditoida:

📜 2005: RFC 4226 (HOTP)

HMAC-Based One-Time Password Algorithm. Suunniteltu vähävirtaisille mikrokontrollereille, joissa on fyysinen painike. Painikkeen painallus kasvattaa sisäistä laskuria ja tulostaa 6-numeroisen koodin LCD-näytölle.

📜 2011: RFC 6238 (TOTP)

Time-Based One-Time Password Algorithm. Suunniteltu älypuhelinten yleistyessä. Hyödyntämällä matkapuhelinverkon NTP-aikasynkronointia TOTP poisti fyysisten painikkeiden tilapoikkeamat kokonaan.

02

HOTP (RFC 4226) -arkkitehtuuri & dynaamisen katkaisun tavumekaniikka

HOTP:n matemaattinen perusmääritelmä on hämäävän tiivis:

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

Parametrien erittely:

  • K: Jaettu symmetrinen salainen avain (tyypillisesti Base32-purettu 160-bittinen / 20-tavuinen binäärijono).
  • C: 8-tavuinen (64-bittinen) big-endian-kokonaislukulaskuri.
  • HMAC-SHA-1: Avaimellinen tiivistefunktio, joka tuottaa 20-tavuisen (160-bittisen) kryptografisen tiivisteen.

🔍 Miten Dynamic Truncation (DT) muuntaa 20 tavua 6 numeroksi:

HMAC-SHA1-tiiviste sisältää 160 bittiä (20 tavua). Kuuden tasaisesti jakautuneen desimaalinumeron poimiminen vaatii deterministisen ja törmäyksiä kestävän valintamekanismin, joka on määritelty RFC 4226:n kohdassa 5.3:

// Vaihe 1: Laske dynaaminen siirtymä (Offset)
Offset = HS[19] & 0x0F
Otetaan 20-tavuisen tiivisteen viimeinen tavu (indeksi 19). Peittaus maskilla 0x0F eristää 4 alinta bittiä, tuottaen kokonaisluvun väliltä 0–15 (0x0–0xF). Tämä varmistaa, ettei sitä seuraava 4 tavun poiminta koskaan ylitä 20-tavuista puskuria (koska 15 + 4 = 19).
// Vaihe 2: Poimi 4 peräkkäistä tavua maskauksella
P = ( (HS[Offset] & 0x7F) << 24 ) | ( (HS[Offset+1] & 0xFF) << 16 ) | ( (HS[Offset+2] & 0xFF) << 8 ) | ( HS[Offset+3] & 0xFF )
Poimitaan 4 tavua alkaen siirtymästä Offset. Maski 0x7F nollaa merkitsevimmän bitin (MSB), jotta vältetään etumerkillisen kokonaisluvun ylivuoto eri suoritinarkkitehtuureissa (varmistaen puhtaan positiivisen 31-bittisen kokonaisluvun).
// Vaihe 3: Modulolaskutoimitus lopullisille numeroille
OTP = P mod 106 = P mod 1000000
Modulo 1 000 000 -operaatio eristää viimeiset 6 desimaalinumeroa ja täydentää tarvittaessa etunollilla (esim. 748:sta tulee "000748").
🧪 Konkreettinen testivektori RFC 4226:n liitteestä D:

Oletetaan, että salainen avain on ASCII-muodossa "12345678901234567890" ja laskuri C = 0. Tuloksena oleva heksadesimaalinen HMAC-SHA1-tiiviste on:

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

1. Viimeinen tavu on 0x71. 0x71 & 0x0F = 0x01, joten Offset = 1.
2. Tavut 1–4 ovat: 93 cf 18 50. MSB-bitin nollaus tuottaa arvon 0x13cf1850, joka on desimaalina 332 339 280.
3. 332339280 mod 1000000 = 339280. Lopullinen 6-numeroinen OTP on 339280!

03

TOTP (RFC 6238) -evoluutio: Aikajaksojen taika

HOTP edellytti, että asiakaslaitteen laskuri pysyy synkronoituna palvelimen kanssa. Ohjelmistolaitteissa näppäilyjen tai painallusten laskeminen aiheuttaa jatkuvasti inhimillisiä virheitä.

RFC 6238 korvasi laskurin C discreetillä aikajaksolla T, joka johdetaan suoraan Unix-aikaleimasta:

T = ⌊ (CurrentUnixTime - T0) / X ⌋
  • CurrentUnixTime: Sekunnit alkaen 1970-01-01 00:00:00 UTC.
  • T0: Epookin aloitearvo (oletuksena 0 kaikissa nykyaikaisissa järjestelmissä).
  • X (Aikajakso): Standardin suosittelema kesto on 30 sekuntia.
  • Lattiafunktio ⌊ ⌋: Millä tahansa aikaleimalla 30 sekunnin ikkunan sisällä T pysyy muuttumattomana. Esimerkiksi epookkisekuntien 1728211200 ja 1728211229 välillä T saa täsmälleen saman 64-bittisen kokonaislukuarvon.

Binääriserialisointi: Kun T on laskettu, se pakataan 8-tavuiseen big-endian-binääripuskuriin (rakenteeltaan identtinen HOTP:n laskurin C kanssa). Yhdistetty kaava yksinkertaistuu siten muotoon:
TOTP(K, Time) = HOTP(K, T) Tämä matemaattinen elegantius selittää, miksi todennussovellukset vaihtavat koodeja synkronoidusti 30 sekunnin välein ilman jatkuvaa tilasynkronointia.

RFC 6238:n tuki SHA-256- ja SHA-512-tiivisteille: Siinä missä RFC 4226 määritteli vain HMAC-SHA-1:n, RFC 6238 laajensi tuen HMAC-SHA-256- ja HMAC-SHA-512-algoritmeille. SHA-256:ssa (32-tavuinen tiiviste) siirtymä otetaan tavusta 31 (HS[31] & 0x0F); SHA-512:ssa (64-tavuinen tiiviste) siirtymä otetaan tavusta 63 (HS[63] & 0x0F). Kuitenkin 99,9 % kaupallisista verkkosivustoista (Google, Microsoft, GitHub, AWS) käyttää edelleen SHA-1:tä taaksepäin yhteensopivuuden vuoksi.
04

Kattava vertailumatriisi (HOTP vs. TOTP)

Dimensio HOTP (RFC 4226) TOTP (RFC 6238)
Syötemuuttuja Tapahtumalaskuri C (monotonisesti kasvava) Aikajakso T (30 sekunnin Unix-epookki-ikkuna)
Koodin elinaika Rajoittamaton (voimassa seuraavaan kirjautumiseen) Tiukasti 30 sekuntia (vanhenee automaattisesti)
Palvelinarkkitehtuuri Tilallinen (vaatii atomisia tietokantakirjoituksia kirjautumista kohti) Tilaton (riippumaton NTP-vahvistus)
Alttius toistohyökkäyksille Kohtalainen (siepattu koodi pysyy voimassa kunnes käytetään) Minimaalinen (rajoittuu kuluvan jakson jäljellä oleviin sekunteihin)
Ensisijainen vikatilanne Laskurin desynkronointi (vahinkopainallukset) Kellon poikkeama (asiakaspuhelimen aikasiirtymä)
Tuetut tiivistefunktiot Vain HMAC-SHA-1 HMAC-SHA-1, HMAC-SHA-256, HMAC-SHA-512
Teollisuuden käyttö Vanhat pankkilaitteet, fyysiset kulunvalvontalaitteet 99,9 % nykyaikaisista verkkotodennussovelluksista
05

Desynkronointi vs. kellopoikkeama: Tekniset ratkaisut

Hajautetuissa tuotantoympäristöissä asiakkaiden ja palvelinten kellot väistämättä poikkeavat toisistaan. Kryptografit suunnittelivat nimenomaisia kompensointi-ikkunoita toimintavarmuuden takaamiseksi:

⚙️ HOTP-ratkaisu: Eteenpäin katsova tarkistusikkuna (s)

Jos käyttäjä painaa token-painiketta 5 kertaa lähettämättä koodia, asiakkaan laskuri saavuttaa arvon C+5 palvelimen pysyessä arvossa C.
RFC 4226 määrittää, että todennuksen yhteydessä palvelin laskee eteenpäin katsovan ikkunan väliltä [C+1, C+s] (tyypillisesti s=20). Jos vastaavuus löytyy, palvelin hyppää eteenpäin ja synkronoi laskurin C välittömästi.

⏱️ TOTP-ratkaisu: Aikapoikkeaman sieto (±1 ikkuna)

Verkkoviiveen tai asiakaslaitteen kellopoikkeaman vuoksi (esim. puhelimen kello 10 sekuntia jäljessä) koodit voivat saapua vierekkäisissä aikajaksoissa.
Tuotantopalvelimet arvioivat 3 ikkunan taulukon: [T-1, T, T+1], mikä laajentaa hyväksymisikkunan 90 sekuntiin.

Pakollinen toistosuojaussääntö: Toistohyökkäysten estämiseksi 90 sekunnin ikkunassa palvelinten on tallennettava ja lukittava käytetyt koodit muistiin (esim. Redis) 90 sekunniksi ja hylättävä päällekkäiset lähetykset.
🛡️ Vakioaikainen merkkijonovertailu (Ajoitushyökkäysten esto):

Kun palvelimet tarkistavat, vastaako käyttäjän koodi laskettua koodia, naiivit merkkijonotarkistukset (kuten userOtp === serverOtp) keskeytyvät heti ensimmäisen virheellisen merkin kohdalla. Hyökkääjä, joka mittaa mikroskooppisia verkon vasteaikoja, voi päätellä numerot iteratiivisesti. Yrityspalvelimet käyttävät vakioaikaista vertailua (kuten crypto.timingSafeEqual Node.js:ssä) estääkseen ajoituskanavahyökkäykset.

06

Miksi TOTP voitti modernin internetin

TOTP:n ratkaiseva voitto HOTP:stä verkkomaailmassa perustui kolmeen arkkitehtoniseen vaatimukseen:

☁️ Tilaton pilviskaalautuvuus

Hajautetuissa monialuemikropalveluissa mikä tahansa NTP-synkronoitu palvelin voi vahvistaa TOTP-koodit ilman keskitetyn tietokantatietueen lukemista tai lukitsemista.

📱 Mobiiliekosysteemin synergia

Älypuhelimet kalibroivat järjestelmäkellonsa jatkuvasti matkapuhelintukiasemien ja GPS:n kautta, poistaen kellopoikkeaman ilman laitteiston fyysistä huoltoa.

🛡️ Kapea 30 sekunnin hyökkäysikkuna

HOTP-koodit pysyvät voimassa toistaiseksi, kunnes ne käytetään. TOTP-koodit vanhenevat 30 sekunnissa, neutraloiden vuotaneet lokit ja passiivisen verkkoliikenteen sieppauksen automaattisesti.

🧮 Puhdas asiakaspään RFC 6238 -moottori

Koe reaaliaikaiset TOTP-laskennat 2FA-Toolissa

Katso, miten salainen Base32-merkkijonosi muuttuu dynaamisiksi 6-numeroisiksi koodeiksi HMAC-SHA1-dynaamisen katkaisun avulla. 100 % offline-tilassa selaimessasi.

Avaa verkkogeneraattori