In einem Satz
TOTP ist ein Algorithmus, der aus einem gemeinsamen Geheimnis und der aktuellen Zeit einen sich ständig ändernden, temporären Zahlencode generiert, der als zweiter Faktor beim Einloggen verwendet wird.
Das Problem, das es löst
Seien wir ehrlich: Passwörter sind ein notwendiges Übel. Wir vergessen sie, wir verwenden sie wieder, und Angreifer sind deprimierend gut darin, sie durch Phishing, Datenbank-Lecks und gutes altes Raten zu stehlen. Sich allein auf ein Passwort zu verlassen, ist, als ob du deine Haustür abschließt, den Schlüssel aber unter die Fußmatte legst.
Hier kommt die Multi-Faktor-Authentifizierung (MFA) und ihre häufigste Variante, die Zwei-Faktor-Authentifizierung (2FA), ins Spiel. Die Idee ist, deine Identität mit mehr als nur etwas, das du weißt (einem Passwort), nachzuweisen. Du brauchst auch etwas, das du hast (wie dein Handy) oder etwas, das du bist (wie deinen Fingerabdruck).
Frühe 2FA bedeutete oft, einen Code per SMS zu erhalten. Das war besser als nichts, ist aber anfällig für „SIM-Swapping“-Angriffe, bei denen ein Betrüger deinen Mobilfunkanbieter davon überzeugt, deine Nummer auf sein Handy zu übertragen. Plötzlich erhält er deine 2FA-Codes. Nicht gerade super.
Hier kommen App-basierte Authenticator ins Spiel. Anstatt sich auf die wackelige Sicherheit des Mobilfunknetzes zu verlassen, kann eine App auf deinem Gerät Codes lokal generieren. Aber woher weiß deine Google Authenticator App, wie sie einen Code für dein GitHub-Konto generieren soll? Und wie weiß dein Microsoft Authenticator, wie er mit deiner Dropbox sprechen soll?
Sie alle sprechen dieselbe Open-Standard-Sprache: TOTP, das Time-Based One-Time Password. TOTP ist der unbesungene Held, der deinen zweiten Faktor von einem einzelnen Unternehmen entkoppelt. Es ist ein offener, interoperabler Standard, der es jeder konformen App ermöglicht, mit jedem konformen Dienst zu arbeiten. Es ist die Weiterentwicklung eines früheren Standards namens HOTP (der auf einem einfachen Zähler basierte), aber durch die Verwendung der Zeit als bewegliches Teil wurde TOTP wesentlich benutzerfreundlicher.
Wie es unter der Haube funktioniert
TOTP scheint wie Magie. Du scannst einmal einen QR-Code, und für den Rest der Zeit können dein Handy und ein Server am anderen Ende der Welt sich alle 30 Sekunden auf dieselbe sechsstellige Zahl einigen, ohne jemals wieder miteinander zu sprechen. Das ist keine Magie, sondern nur echt cleverer Krypto-Kram.
Schauen wir uns das Rezept mal genauer an.
Das gemeinsame Geheimnis: Der Schlüssel zum Königreich
Alles beginnt mit einem Geheimnis. Wenn du 2FA bei einem Dienst aktivierst, generiert der Server einen zufälligen, geheimen Schlüssel (z. B. 160 Bit pure Zufälligkeit). Dieses Geheimnis ist das Einzige, was sowohl du als auch der Server wissen müssen. Die gesamte Sicherheit des Systems beruht darauf, es geheim zu halten.
Natürlich ist eine Zeichenkette aus 160 zufälligen Bits nicht sehr benutzerfreundlich. Für uns Menschen wird sie daher in ein Format namens Base32 kodiert. Im Gegensatz zu seinem Cousin Base64 verwendet Base32 ein kleineres Alphabet, bei dem Groß- und Kleinschreibung keine Rolle spielen und das zweideutige Zeichen wie 1 und l oder 0 und O vermeidet. Das macht es möglich (wenn auch immer noch nervig), es manuell einzugeben, falls du den QR-Code nicht scannen kannst.
Ein typisches Base32-Geheimnis sieht so aus: JBSWY3DPEHPK3PXPJBSWY3DPEHPK3PXP
Der häufigste Weg, dieses Geheimnis in deine Authenticator-App zu bekommen, ist über einen QR-Code, der eine spezielle URI kodiert:
otpauth://totp/FlowingDev:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=FlowingDev
Deine App scannt dies, speichert den Aussteller (issuer, FlowingDev), den Kontonamen (user@example.com) und vor allem das secret. Der Handschlag ist vollzogen.
Das bewegliche Teil: Die Zeit
Das „T“ in TOTP steht für Time-Based (zeitbasiert). Das ist die entscheidende Zutat, die den Code veränderlich macht. Das System verwendet jedoch nicht die exakte Zeit bis auf die Millisekunde – das wäre unmöglich zu synchronisieren. Stattdessen verwendet es einen diskreten Zeit-Schritt.
Die Formel ist einfach:
TimeStep = floor(CurrentUnixTime / 30)
- CurrentUnixTime: Die Anzahl der Sekunden, die seit dem 1. Januar 1970 vergangen sind (die Unix-Epoche).
- / 30: Der Zeitschritt beträgt fast universell 30 Sekunden.
Diese Berechnung ergibt eine ganze Zahl, die sich nur alle 30 Sekunden ändert. Um 10:00:00 Uhr hat der TimeStep einen bestimmten Wert T. Um 10:00:29 Uhr ist er immer noch T. Aber um 10:00:30 Uhr erhöht er sich auf T+1. Dieser TimeStep ist die „Nachricht“, die wir authentifizieren werden.
Die Krypto-Magie: HMAC-SHA1
Jetzt kombinieren wir das statische Geheimnis mit dem beweglichen Zeitschritt. Dies geschieht mit einer kryptografischen Primitivfunktion namens HMAC (Hash-based Message Authentication Code).
HMAC_Result = HMAC-SHA1(SecretKey, TimeStep)
Stell dir HMAC als eine Methode vor, eine sichere Signatur zu erstellen. Es nimmt unseren geheimen Schlüssel und die Daten, die wir signieren wollen (den TimeStep), und vermischt sie mithilfe einer Hash-Funktion – in diesem Fall dem ehrwürdigen SHA-1.
Das Ergebnis ist ein 20-Byte (160-Bit) Hash. Es ist ein langer, hexadezimaler String, der für genau dieses Geheimnis und diesen spezifischen Zeitschritt absolut einzigartig ist. Ändere nur ein Bit des Geheimnisses oder warte 30 Sekunden, bis sich der Zeitschritt ändert, und du erhältst einen völlig anderen Hash.
Obwohl SHA-1 für andere Zwecke wie das Signieren von Zertifikaten bekannte Schwächen hat, gilt es innerhalb der HMAC-Konstruktion immer noch als vollkommen sicher. Viele moderne Implementierungen wechseln zur Sicherheit zu HMAC-SHA256 oder HMAC-SHA512.
Die Kürzung: Auf zum sechsstelligen Code
Ein 20-Byte-Hex-String ist kein benutzerfreundlicher sechsstelliger Code. Der letzte Schritt besteht darin, diesen Hash dynamisch in eine Zahl zu „kürzen“, die wir tatsächlich verwenden können.
- Den Offset finden: Schau dir die allerletzten 4 Bits (Nibble) des 20-Byte-HMAC-Ergebnisses an. Das gibt uns eine Zahl zwischen 0 und 15. Das ist unser
offset. - 4 Bytes schnappen: Beginnend an dieser
offset-Position im 20-Byte-Hash, nimm die nächsten 4 Bytes (32 Bits). - Das oberste Bit löschen: Nimm diesen 32-Bit-Block und führe ein bitweises UND mit
0x7FFFFFFFdurch. Das entfernt effektiv das allererste Bit, was einige potenzielle Probleme mit vorzeichenbehafteten vs. vorzeichenlosen Integern löst und sicherstellt, dass das Ergebnis immer positiv ist. - Modulo-Action! Jetzt hast du eine große 31-Bit-Ganzzahl. Um sie auf 6 Ziffern zu bringen, nimmst du sie modulo 1.000.000 (
10^6). - Mit Nullen auffüllen: Das Ergebnis ist dein Code! Wenn die Zahl zum Beispiel
4521ist, füllst du sie mit führenden Nullen auf, um004521zu erhalten.
Das war's! Sowohl dein Handy als auch der Server führen exakt dieselbe Berechnung durch. Wenn du den Code eingibst, vergleicht der Server sein Ergebnis mit deinem. Um leichte Uhrzeitabweichungen zwischen deinem Handy und dem Server auszugleichen, prüft der Server typischerweise den Code für den aktuellen Zeitschritt, den davor und den danach. Wenn einer davon übereinstimmt, bist du drin.
Geschichten aus der Praxis
Die verhinderte Übernahme eines GitHub-Kontos
Ein Entwickler, tief in seiner Arbeit versunken, erhält eine E-Mail, die exakt so aussieht, als käme sie von GitHub und warnt vor einem Sicherheitsproblem. In einem unachtsamen Moment klickt er auf den Link, landet auf einem pixelgenauen Klon der GitHub-Login-Seite und gibt seinen Benutzernamen und sein Passwort ein. Der Angreifer hat jetzt seine Zugangsdaten. Der Phisher versucht sofort, sich beim echten GitHub anzumelden. Er gibt das gestohlene Passwort ein ... und wird mit einer Aufforderung konfrontiert: „Bitte geben Sie Ihren Zwei-Faktor-Authentifizierungscode ein.“ Der Angreifer steckt komplett fest. Er hat nicht das Handy des Entwicklers und keine Möglichkeit, den TOTP-Code zu generieren. Der Entwickler erhält unterdessen eine echte E-Mail von GitHub über einen neuen Login, erkennt seinen Fehler und ändert sofort sein Passwort.
Lektion: TOTP fungiert als entscheidende Firewall. Es verwandelt einen potenziell katastrophalen Passwort-Diebstahl in einen harmlosen, fehlgeschlagenen Anmeldeversuch.
Der Notfallzugriff im Offline-Modus
Ein Netzwerkingenieur ist auf dem Flug zu einer Konferenz. Dreißig Minuten nach dem Start muss er ein kritisches Produktivsystem überprüfen. Es gibt kein WLAN im Flugzeug und null Mobilfunkempfang. Eine SMS- oder Push-basierte 2FA wäre nutzlos. Aber sein Dashboard ist mit TOTP gesichert. Er klappt seinen Laptop auf, ruft die Anmeldeseite auf, öffnet die Authenticator-App auf seinem Handy und gibt den sechsstelligen Code ein. Die App benötigt keine Internetverbindung; ihre Mathematik ist in sich geschlossen und basiert nur auf dem gemeinsamen Geheimnis und der internen Uhr des Handys. Er loggt sich ein und löst das Problem, noch bevor die Flugbegleiter mit dem Getränkeservice beginnen.
Lektion: Die Fähigkeit von TOTP, vollständig offline zu funktionieren, macht es unglaublich robust und zuverlässig für kritische Zugriffe, egal wo du bist.
Die Kopfschmerzen bei der plattformübergreifenden Migration... gelöst
Ein langjähriger Android-Nutzer beschließt, auf ein iPhone umzusteigen. Er öffnet Google Authenticator und stellt entsetzt fest, dass es keinen einfachen Button „Mit meinem neuen Handy synchronisieren“ gibt. Er hat über 30 Konten eingerichtet, und der Gedanke, für jedes einzelne den 2FA-Reset-Prozess durchlaufen zu müssen, ist ein Albtraum. Aber dann erinnert er sich an seine persönliche Sicherheitsrichtlinie: Für jeden neuen Dienst hat er den ursprünglichen QR-Code als Screenshot in seinem verschlüsselten Passwort-Manager gespeichert. Er installiert eine neue Authenticator-App auf seinem iPhone, öffnet seinen Passwort-Manager und scannt nacheinander die gespeicherten QR-Codes erneut. In zehn Minuten sind alle 30 Konten migriert und funktionieren einwandfrei.
Lektion: Das TOTP-Geheimnis (als Base32-String oder QR-Code) ist der eigentliche Schlüssel. Indem du deine Geheimnisse sicher sicherst und so von einer einzelnen Authenticator-App unabhängig bist, erlangst du echtes Eigentum und Portabilität.
Häufige Fehler und Fallen
- Das Geheimnis leichtfertig behandeln. Der QR-Code oder der Base32-String, den du bei der Einrichtung erhältst, ist der geheime Schlüssel. Wenn ein Angreifer ihn in die Hände bekommt, kann er für immer gültige Codes generieren. Mach keinen Screenshot davon und lass ihn auf deinem Desktop liegen, schick ihn dir nicht per E-Mail und speichere ihn nicht in einer reinen Textdatei. Behandle ihn wie ein Master-Passwort.
- Vergessen, Wiederherstellungscodes zu speichern. Wenn du 2FA aktivierst, stellt dir fast jeder Dienst eine Reihe von einmalig verwendbaren Wiederherstellungscodes zur Verfügung. DRUCK SIE AUS. Bewahre sie an einem sicheren Ort auf (in einem echten Safe oder zumindest in deinem Passwort-Manager). Wenn du dein Handy verlierst, sind diese Codes dein einziger Weg zurück in dein Konto, ohne einen schmerzhaften Support-Prozess.
- Annehmen, dass deine Authenticator-App gesichert ist. Viele einfache Authenticator-Apps (wie der ursprüngliche Google Authenticator) speichern Geheimnisse nur auf diesem einen Gerät. Wenn das Handy verloren geht oder zurückgesetzt wird, sind die Geheimnisse für immer weg. Verwende eine App, die eine sichere, verschlüsselte Cloud-Synchronisierung bietet (wie Authy oder 1Password) oder sei diszipliniert beim manuellen Sichern deiner Geheimnisse.
- Uhrzeitabweichungen ignorieren. TOTP ist zeitbasiert. Wenn die Uhr deines Handys um mehr als ein oder zwei Minuten von der Echtzeit abweicht, werden die generierten Codes abgelehnt. Stelle dein Handy und deinen Computer immer auf „Zeit automatisch einstellen“ ein. Das ist fast immer der Übeltäter, wenn gültige Codes plötzlich nicht mehr funktionieren.
Warum du es auf dem Schirm haben solltest
Wenn du als Entwickler ein System mit Benutzerkonten baust, solltest du MFA implementieren, und TOTP ist die erstklassige Open-Standard-Option für App-basierte 2FA. Es ist sicherer als SMS und offener als proprietäre Push-Benachrichtigungssysteme. Zu verstehen, wie man ein Geheimnis generiert, eine otpauth://-URI erstellt und ein eingehendes Token validiert, ist eine grundlegende Fähigkeit für die Entwicklung sicherer Anwendungen.
Selbst wenn du nie selbst ein TOTP-System implementierst, bist du ein Nutzer davon auf Plattformen wie AWS, Cloudflare, GitHub und npm. Zu wissen, wie die Magie unter der Haube funktioniert, ermöglicht dir, es sicherer zu verwenden. Es hilft dir, die Bedeutung des Schutzes des ursprünglichen Geheimnisses, des Speicherns deiner Wiederherstellungscodes und der Wahl der richtigen Authenticator-App für deine Bedürfnisse zu verstehen. Es entmystifiziert die kleine sechsstellige Zahl, die zwischen deinen Daten und den Bösen steht.
Geh tiefer
- RFC 6238: Time-Based One-Time Password Algorithm – Die offizielle Spezifikation für TOTP.
- RFC 4226: HMAC-Based One-Time Password Algorithm – Die Spezifikation für HOTP, das Fundament, auf dem TOTP aufbaut.
- RFC 4648: The Base16, Base32, and Base64 Data Encodings – Die Spezifikation, die die Base32-Kodierung für die Weitergabe von Geheimnissen definiert.
- Key URI Format · google/google-authenticator Wiki – Der De-facto-Standard für die in QR-Codes verwendete
otpauth://-URI. - Time-based One-time Password - Wikipedia – Ein übergeordneter und historischer Überblick über den Algorithmus.