⏱️ Cryptografie & RFC-protocollen ✓ Analyse van IETF-standaarden

TOTP vs HOTP uitgelegd: kernverschillen, beveiliging & werkingsprincipes

Miljoenen ontwikkelaars en beveiligingsengineers zien dagelijks wisselende 6-cijferige verificatiecodes, maar weinigen begrijpen het elegante wiskundige mechanisme dat zich onder het scherm afspeelt. Van de op gebeurtenissen gebaseerde tellers van RFC 4226 (HOTP) in 2005 tot de discrete tijdstappen van RFC 6238 (TOTP) in 2011: deze handleiding onderzoekt het dynamische truncatie-algoritme op byteniveau, kwetsbaarheden door desynchronisatie van tellers, toleranties voor klokafwijking en waarom TOTP het moderne internet veroverde.

2FA
2FA-Tool beveiligingsteam
Bijgewerkt: oktober 2026
Geschatte leestijd: 14 min (2.600+ woorden)
RFC 6238 RFC 4226 Dynamische truncatie
💡 Belangrijkste cryptografische inzichten (TL;DR)
  • Het fundamentele verschil in invoer: HOTP berekent hashes op basis van een monotoon oplopende teller C, terwijl TOTP C vervangt door een discrete tijdstap T (HuidigeUnixTijd / 30).
  • Directe overerving: TOTP is wiskundig gezien een specialisatie van HOTP: TOTP(K, Tijd) = HOTP(K, T). Beide algoritmen gebruiken exact dezelfde functie voor dynamische truncatie.
  • De doorslaggevende architectuurfactor: HOTP is stateful (servers moeten tellers bij elke validatie vergrendelen en naar schijf schrijven). TOTP is stateless, waardoor moderne cloud-microservices tokens kunnen valideren over gedistribueerde load-balanced clusters zonder gecentraliseerde databaseschrijfacties.
01

Historische wortels: van gesloten hardwaretokens naar open webstandaarden

Begin jaren 2000 werd tweefactorauthenticatie in het bedrijfsleven gedomineerd door gesloten hardwaretokens zoals RSA SecurID. Deze dure, propriëtaire apparaten bevatten interne kwartskristallen die gesynchroniseerd waren met propriëtaire bedrijfsservers. Als een organisatie duizenden werknemers wilde voorzien van multifactorbeveiliging, waren de hardware- en licentiekosten torenhoog.

Om authenticatie te bevrijden van gesloten leveranciers, richtten marktleiders het OATH (Initiative for Open Authentication)-consortium op om open, royaltyvrije IETF-standaarden te ontwikkelen die elke softwareontwikkelaar vrij kon inzien, implementeren en controleren:

📜 2005: RFC 4226 (HOTP)

HMAC-Based One-Time Password Algorithm. Ontworpen voor microcontrollers met een laag stroomverbruik en fysieke drukknoppen. Een druk op de knop verhoogt een interne teller en toont een 6-cijferig token op een lcd-schermpje.

📜 2011: RFC 6238 (TOTP)

Time-Based One-Time Password Algorithm. Ontworpen tijdens de opkomst van smartphones. Door gebruik te maken van tijdsynchronisatie via NTP via het mobiele netwerk, elimineerde TOTP statusverschillen door fysieke knoppen volledig.

02

HOTP (RFC 4226)-architectuur & bytemechanisme van dynamische truncatie

De wiskundige kerndefinitie van HOTP is bedrieglijk beknopt:

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

Verklaring van parameters:

  • K: Gedeelde symmetrische geheime sleutel (doorgaans een gedecodeerde Base32 binaire reeks van 160 bits / 20 bytes).
  • C: 8-byte (64-bit) big-endian integer-teller.
  • HMAC-SHA-1: Keyed-hash berichtauthenticatiecode die een cryptografische digest van 20 bytes (160 bits) genereert.

🔍 Hoe dynamische truncatie (DT) 20 bytes omzet in 6 cijfers:

Een HMAC-SHA1-digest bevat 160 bits (20 bytes). Het extraheren van 6 uniforme decimale cijfers vereist een deterministisch, botsingsbestendig selectiemechanisme dat is gedefinieerd in sectie 5.3 van RFC 4226:

// Stap 1: Dynamische offset berekenen
Offset = HS[19] & 0x0F
Neem de laatste byte (index 19) van de 20-byte digest. Maskeren met 0x0F isoleert de laagste 4 bits, wat een geheel getal oplevert dat strikt tussen 0 en 15 (0x0 tot 0xF) ligt. Dit garandeert dat de daaropvolgende 4-byte extractie nooit buiten de buffer van 20 bytes treedt (aangezien 15 + 4 = 19).
// Stap 2: 4 opeenvolgende bytes extraheren met maskering
P = ( (HS[Offset] & 0x7F) << 24 ) | ( (HS[Offset+1] & 0xFF) << 16 ) | ( (HS[Offset+2] & 0xFF) << 8 ) | ( HS[Offset+3] & 0xFF )
Extraheer 4 bytes vanaf Offset. Het masker 0x7F zet de meest significante bit op nul om signed integer overflow op verschillende CPU-architecturen te voorkomen (wat een zuiver positief 31-bits geheel getal garandeert).
// Stap 3: Modulo-berekening voor de uiteindelijke cijfers
OTP = P mod 106 = P mod 1000000
Het toepassen van modulo 1.000.000 isoleert de laatste 6 decimale cijfers, eventueel links aangevuld met voorloopnullen (bijv. 748 wordt "000748").
🧪 Concrete testvector uit RFC 4226 Appendix D:

Stel dat de geheime sleutel ASCII "12345678901234567890" is en teller C = 0. De resulterende HMAC-SHA1-digest in hexadecimaal is:

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

1. De laatste byte is 0x71. 0x71 & 0x0F = 0x01, dus Offset = 1.
2. Bytes 1 t/m 4 zijn: 93 cf 18 50. Het wissen van de MSB levert 0x13cf1850 op, wat in decimaal gelijk is aan 332.339.280.
3. 332339280 mod 1000000 = 339280. De resulterende 6-cijferige OTP is 339280!

03

De evolutie naar TOTP (RFC 6238): de magie van de tijdstap

Bij HOTP moest de teller op de client synchroon worden gehouden met die op de server. Op softwareapparaten zorgt het tellen van toetsaanslagen of knopdrukken voor onvermijdelijke menselijke fouten.

RFC 6238 verving teller C door een discrete tijdstap T, rechtstreeks afgeleid van de Unix epoch-klok:

T = ⌊ (HuidigeUnixTijd - T0) / X ⌋
  • HuidigeUnixTijd: Seconden verstreken sinds 1970-01-01 00:00:00 UTC.
  • T0: Referentiepunt voor epoch-initialisatie (standaard 0 in alle moderne toepassingen).
  • X (Tijdstapvenster): Standaard aanbevolen duur van 30 seconden.
  • Afrondingsfunctie ⌊ ⌋ (Floor): Voor elk tijdstempel binnen een venster van 30 seconden blijft T constant. Tussen bijvoorbeeld epoch-seconden 1728211200 en 1728211229 levert T exact hetzelfde 64-bits gehele getal op.

Binaire serialisatie: Zodra T is berekend, wordt deze verpakt in een 8-byte big-endian binaire bytebuffer (qua geheugenstructuur identiek aan teller C in HOTP). Daardoor vereenvoudigt de uniforme formule tot:
TOTP(K, Tijd) = HOTP(K, T) Deze wiskundige elegantie verklaart waarom authenticator-apps tokens elke 30 seconden synchroon vernieuwen zonder dat er permanente statussynchronisatie nodig is.

Ondersteuning voor SHA-256 en SHA-512 in RFC 6238: Waar RFC 4226 zich strikt beperkte tot HMAC-SHA-1, breidde RFC 6238 de ondersteuning uit naar HMAC-SHA-256 en HMAC-SHA-512. Bij SHA-256 (32-byte digest) wordt de offset gehaald uit byte 31 (HS[31] & 0x0F); bij SHA-512 (64-byte digest) uit byte 63 (HS[63] & 0x0F). Op 99,9% van de commerciële websites (Google, Microsoft, GitHub, AWS) blijft SHA-1 echter de universele standaard vanwege compatibiliteit met oudere mobiele clients.
04

Uitgebreide vergelijkingsmatrix (HOTP vs. TOTP)

Dimensie HOTP (RFC 4226) TOTP (RFC 6238)
Invoervariabele Gebeurtenisenteller C (monotoon oplopend) Tijdstap T (Unix-epochvenster van 30 seconden)
Geldigheidsduur van token Onbepaald (geldig tot verbruikt bij volgende login) Strikt 30 seconden (vervalt automatisch)
Serverarchitectuur Stateful (vereist atomair wegschrijven naar database per login) Stateless (onafhankelijke verificatie via NTP)
Risico op replay-aanvallen Matig (onderschept token blijft geldig tot het gebruikt wordt) Minimaal (beperkt tot resterende seconden in huidig venster)
Belangrijkste storingsfactor Tellersynchronisatieverlies (per ongeluk indrukken van knop) Tijdsafwijking (klokafwijking op mobiele client)
Ondersteunde cryptografische hashes Uitsluitend HMAC-SHA-1 HMAC-SHA-1, HMAC-SHA-256, HMAC-SHA-512
Toepassing in de praktijk Verouderde banktokens, fysieke toegangscontrole 99,9% van moderne online authenticators
05

Desynchronisatie vs. tijdsafwijking: technische oplossingen

In gedistribueerde productieomgevingen treedt onvermijdelijk afwijking op tussen clients en servers. Cryptografen hebben hiervoor specifieke tolerantievensters ontworpen om betrouwbaarheid te waarborgen:

⚙️ HOTP-oplossing: Vooruitkijkvenster (s)

Als een gebruiker 5 keer op zijn tokenknop drukt zonder in te loggen, staat de teller van de client op C+5 terwijl de server nog op C staat.
RFC 4226 schrijft voor dat de server bij authenticatie een vooruitkijkvenster berekent over [C+1, C+s] (meestal s=20). Als er een overeenkomst wordt gevonden, springt de server vooruit en synchroniseert deze teller C onmiddellijk.

⏱️ TOTP-oplossing: Tolerantie voor tijdsafwijking (±1 venster)

Door netwerklatentie of klokafwijking op het apparaat van de client (bijv. een telefoonklok die 10 seconden achterloopt), kunnen tokens in aangrenzende tijdstappen binnenkomen.
Productieservers evalueren een matrix van 3 vensters: [T-1, T, T+1], waardoor het acceptatievenster effectief wordt verruimd naar 90 seconden.

Verplichte anti-replay-regel: Om replay-aanvallen binnen het tolerantievenster van 90 seconden te voorkomen, moeten servers verbruikte tokens gedurende 90 seconden in het geheugen cachen en vergrendelen (bijv. via Redis) en dubbele inzendingen weigeren.
🛡️ Vergelijking in constante tijd (bescherming tegen timingaanvallen):

Wanneer servers controleren of de door de gebruiker ingevoerde code overeenkomt met de berekende code, stopt een naïeve stringvergelijking (zoals userOtp === serverOtp) direct bij het eerste afwijkende teken. Een aanvaller die microscopisch kleine roundtrip-tijden via het netwerk meet, kan cijfers stapsgewijs reconstrueren. Zakelijke backends dwingen vergelijkingen in constante tijd af (zoals crypto.timingSafeEqual in Node.js) om timingaanvallen via side-channels te voorkomen.

06

Waarom TOTP het moderne internet veroverde

De doorslaggevende overwinning van TOTP op HOTP werd aangedreven door drie fundamentele architectuurvoordelen:

☁️ Stateless schaalbaarheid in de cloud

In gedistribueerde microservices over meerdere regio's kan elke serverinstantie met een NTP-gesynchroniseerde klok TOTP-tokens valideren zonder een centrale database te raadplegen of te vergrendelen.

📱 Synergie met het mobiele ecosysteem

Smartphones synchroniseren hun systeemklok continu via zendmasten en GPS, waardoor klokafwijkingen worden geëlimineerd zonder fysiek onderhoud aan hardware.

🛡️ Smal aanvalsoppervlak van 30 seconden

HOTP-tokens blijven oneindig geldig tot ze gebruikt worden. TOTP-tokens vervallen binnen 30 seconden, waardoor gecompromitteerde logs en passief afgeluisterde pakketten automatisch waardeloos worden.

🧮 Zuivere client-side RFC 6238-engine

Ervaar real-time TOTP-berekeningen in 2FA-Tool

Zie hoe uw geheime Base32-sleutel wordt getransformeerd in dynamische 6-cijferige codes via HMAC-SHA1 dynamische truncatie. 100% offline in uw browser.

Open online generator