TOTP-/2FA-Code-Debugger
Erzeuge und debugge TOTP-/2FA-Codes: die vollständige RFC-6238-Ableitung, Verifizierung mit Drift-Fenster und otpauth://-Analyse — alles im Browser.
Gib ein Geheimnis ein, um einen Code zu sehen.
otpauth://totp/user%40example.com?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&period=30Was die sechs Ziffern wirklich sind
Ein TOTP-Code — die Zahl, die eine Authenticator-App alle dreißig Sekunden weiterschaltet — ist weder zufällig noch irgendwo gespeichert. Er wird berechnet, sowohl auf deinem Telefon als auch auf dem Server, aus zwei Dingen, die sie bereits teilen: einem Geheimnis, das einmal beim Aktivieren der Zwei-Faktor-Authentifizierung eingerichtet wurde, und der aktuellen Zeit. Da beide Seiten ihn unabhängig berechnen können, muss beim Anmelden nichts zwischen ihnen reisen; der Server führt einfach dieselbe Berechnung aus und prüft, ob seine Antwort mit deiner übereinstimmt.
TOTP (RFC 6238) ist eine dünne Schicht über einem älteren Verfahren, HOTP (RFC 4226). HOTP macht aus einem Geheimnis und einem Zähler einen Code; TOTP ist einfach HOTP mit dem Zähler auf die Anzahl der Zeitschritte seit der Unix-Epoche gesetzt. Das ist die ganze Idee: Teile die aktuelle Unix-Zeit durch die Schrittlänge (standardmäßig 30 Sekunden) und gib das Ergebnis an HOTP. Dieses Werkzeug zeigt jeden Schritt dieser Berechnung, denn wenn ein Code nicht verifiziert, ist die Antwort fast immer irgendwo in der Ableitung sichtbar.
Die Ableitung, Schritt für Schritt
Fünf Schritte führen vom Geheimnis und der Zeit zu den Ziffern, die du eingibst. Das Werkzeug druckt jeden aus, damit du mit deiner eigenen Implementierung vergleichen kannst:
- Der Zähler. Nimm die Unix-Zeit in Sekunden, ziehe T0 ab (0 in jeder echten Bereitstellung), teile durch die Periode und runde ab. Bei 30-Sekunden-Schritten ergibt jeder Moment in derselben halben Minute denselben Zähler, weshalb ein Code so lange gilt, wie er gilt.
- Der HMAC. Schreibe den Zähler als 8 Byte big-endian und berechne HMAC(Geheimnis, Zähler) mit dem gewählten Hash — SHA-1 bei fast jeder App. Das ergibt einen 20-Byte-Digest für SHA-1 (32 für SHA-256, 64 für SHA-512).
- Der Versatz. Nimm die vier niederwertigen Bits des letzten Byte des Digests. Das ist eine Zahl von 0 bis 15 und sagt, wo im Digest zu lesen ist — dynamische Kürzung, damit dasselbe Geheimnis nicht immer dieselben Bytes verwendet.
- Der 31-Bit-Wert. Lies vier Bytes ab dem Versatz und maskiere das oberste Bit aus (um Vorzeichenverwirrung zu vermeiden). Es bleibt eine 31-Bit-Ganzzahl.
- Der Code. Nimm diese Ganzzahl modulo 10^Ziffern und fülle links mit Nullen auf. Sechs Ziffern sind die nahezu universelle Wahl; sieben und acht existieren und sind erlaubt.
Das Ausmaskieren des obersten Bits und das Modulo sind die einzigen verlustbehafteten Schritte: Viele verschiedene Digests bilden auf dieselben sechs Ziffern ab, und das ist in Ordnung, denn der Code muss nur in den dreißig Sekunden, die er lebt, schwer zu erraten sein, nicht für immer eindeutig.
Warum ein Code nicht passt — die drei üblichen Ursachen
Eine TOTP-Abweichung kommt nie mit einer Fehlermeldung; der Code ist einfach falsch. In der Praxis ist es fast immer eines von drei Dingen, und die Panels hier sind angeordnet, um sie auseinanderzuhalten:
- Das Geheimnis wurde im falschen Format gelesen. Ein Authenticator-Geheimnis ist Base32, aber dieselben Zeichen als Hex gelesen — oder ein Geheimnis, das eigentlich Hex war, als Base32 gelesen — ergeben völlig andere Bytes und einen völlig anderen Code. Schalte den Format-Umschalter um und sieh, welcher den erwarteten Code liefert.
- Ein Parameter weicht ab. Der überwältigende Standard ist HMAC-SHA-1, 6 Ziffern, eine 30-Sekunden-Periode. Ein Server mit SHA-256, oder 8 Ziffern, oder einem 60-Sekunden-Schritt wird einer App widersprechen, die auf den Standardwerten belassen wurde. Die otpauth:// URI trägt alle drei, weshalb das Scannen eines QR sie richtig erwischt und das händische Eintippen eines Geheimnisses oft nicht.
- Die Uhren sind abgedriftet. TOTP nimmt an, dass beide Seiten sich über die Zeit einig sind. Geht die Uhr eines Telefons eine Minute vor, ist sein Code eine Minute vor dem des Servers. Dafür ist das Drift-Fenster da: Einen Code gegen die Schritte beiderseits des Jetzt zu prüfen sagt nicht nur, ob er passt, sondern wie weit die Uhr abweicht.
RFC 6238 empfiehlt ein Validierungsfenster von höchstens einem Schritt auf jeder Seite — genug, um gewöhnliche Uhrenabweichung und das Wettrennen im Umschaltmoment abzufangen, ohne den Suchraum mehr als nötig zu vergrößern. Dieses Werkzeug nutzt standardmäßig ±1 und lässt dich es beim Debuggen erweitern.
Geheimnisse, Base32 und die otpauth:// URI
Das Geheimnis wird einmal geteilt, bei der Einrichtung, und alles danach wird daraus abgeleitet. Authenticator-Apps kodieren es in Base32 (RFC 4648) — das Alphabet A–Z und 2–7, das die leicht verwechselbaren Zeichen vermeidet und das Drucken unter einem QR übersteht. Dieses Werkzeug liest standardmäßig Base32, ignoriert die Leerzeichen, die Apps zur Lesbarkeit hinzufügen, und die Groß-/Kleinschreibung, und akzeptiert auch Hex, damit du die Testvektoren von RFC 6238 reproduzieren kannst, deren Geheimnisse als rohe Bytes angegeben sind.
Der QR-Code, den du bei der Einrichtung scannst, ist auch keine Magie: Er kodiert eine otpauth:// URI im Klartext, die das Geheimnis und alle Parameter trägt. Füge eine hier ein, um die Felder zu füllen, oder baue eine aus den Feldern, um eine Einrichtung zwischen Apps zu verschieben:
otpauth://totp/GitHub:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=GitHub&algorithm=SHA1&digits=6&period=30
Nur der Typ totp wird akzeptiert. Eine otpauth://hotp URI trägt einen Zähler statt einer Periode, und sie als TOTP zu behandeln würde stillschweigend falsche Codes erzeugen — sie wird also abgelehnt statt geraten.
Algorithmus, Ziffern und Periode
RFC 6238 erlaubt HMAC-SHA-1, SHA-256 oder SHA-512, sechs bis acht Ziffern und jede Schrittlänge. In der Praxis hat sich die Welt auf SHA-1, sechs Ziffern und dreißig Sekunden festgelegt, und die meisten Apps implementieren nur diese Kombination — ein Server, der etwas anderes wählt, muss hoffen, dass die App des Nutzers folgt, und viele tun es nicht. Die sichere Wahl für Interoperabilität ist die langweilige.
Es lohnt sich, die SHA-1-Frage direkt anzugehen, denn das Hash-Werkzeug auf dieser Seite markiert SHA-1 als gebrochen. Beide Aussagen sind wahr. SHA-1 ist für digitale Signaturen unbrauchbar, weil Angreifer Kollisionen herstellen können — zwei Dokumente mit demselben Hash. TOTP hängt nicht von dieser Eigenschaft ab: Seine Sicherheit kommt vom geheimen Schlüssel im HMAC, nicht von der Kollisionsresistenz des Hashes, und HMAC-SHA-1 bleibt solide. SHA-256 hier zu verwenden ist vertretbar, bringt aber wenig und kostet Interoperabilität mit Apps, die nur SHA-1 können.
Was dieses Werkzeug schützt und was nicht
Alles hier läuft in deinem Browser. Der HMAC wird mit der Web Crypto API auf deinem eigenen Gerät berechnet, dasselbe Primitiv, das die Hash- und HMAC-Werkzeuge nutzen, und nichts, was du eingibst — Geheimnis, Code oder otpauth URI — wird hochgeladen, gespeichert oder protokolliert. Das ist eine Eigenschaft davon, dass der Code clientseitig ist, kein Versprechen, das du glauben musst.
Dennoch ist ein TOTP-Geheimnis ein zweiter Faktor: Wer es hat, kann deine Codes erzeugen. Ein Produktionsgeheimnis in irgendeine Webseite einzufügen — auch diese — bringt es in die Zwischenablage und womöglich in den Browserverlauf, also behandle es mit derselben Sorgfalt wie ein Passwort und bevorzuge ein Wegwerf- oder Testgeheimnis, wenn du nur den Mechanismus verstehen willst. Das Werkzeug dient zum Debuggen und Lernen, nicht als Ort, an dem dein echter zweiter Faktor lebt.
Häufig gestellte Fragen
- Wird mein Geheimnis an einen Server gesendet?
- Nein. Der Code wird in deinem Browser mit der Web Crypto API berechnet, und nichts, was du eingibst, wird hochgeladen oder protokolliert. Da ein TOTP-Geheimnis ein zweiter Faktor ist, sei trotzdem vorsichtig beim Einfügen eines Produktionsgeheimnisses — es kann wie jeder Text durch die Zwischenablage und den Browserverlauf laufen.
- Warum passt mein Code nicht zu meiner Authenticator-App?
- Fast immer eines von drei Dingen: Das Geheimnis wurde im falschen Format gelesen (Base32 vs Hex), ein Parameter weicht von den Standardwerten ab (die meisten Apps sind SHA-1, 6 Ziffern, 30-Sekunden-Periode), oder die Geräteuhr ist abgedriftet. Das Ableitungs-Panel isoliert die ersten beiden, und die Prüfung mit einem ±-Drift-Fenster deckt das dritte auf.
- Was ist der Unterschied zwischen TOTP und HOTP?
- HOTP (RFC 4226) berechnet einen Code aus einem Geheimnis und einem Zähler, der bei jeder Nutzung hochzählt. TOTP (RFC 6238) ist dieselbe Konstruktion mit dem Zähler auf die Anzahl der Zeitschritte seit der Unix-Epoche gesetzt, sodass sich der Code mit der Uhr statt mit einem Tastendruck ändert. TOTP ist, was Authenticator-Apps verwenden.
- Warum ist SHA-1 der Standard, wenn es anderswo gebrochen ist?
- SHA-1 ist für Signaturen gebrochen, weil sich Kollisionen konstruieren lassen, aber HMAC — worauf TOTP aufbaut — hängt nicht von Kollisionsresistenz ab; seine Sicherheit ruht auf dem geheimen Schlüssel. HMAC-SHA-1 ist solide und der einzige Algorithmus, den viele Authenticator-Apps implementieren, also ist es der sowohl sichere als auch kompatible Standard.
- Kann ich den Code auf eine bestimmte Zeit fixieren?
- Ja. Schalte die Zeit von live auf fixiert und gib einen Unix-Zeitstempel ein. Der Code bleibt dann statisch, so reproduziert man einen veröffentlichten Testvektor — RFC 6238 gibt Werte zu Zeiten wie 59 und 1111111109 — oder prüft, welcher Code zu einem vergangenen Moment gültig war.
- Wie groß sollte das Drift-Fenster sein?
- RFC 6238 empfiehlt höchstens einen Schritt auf jeder Seite, was dieses Werkzeug standardmäßig nutzt. Ein breiteres Fenster toleriert eine stärker abgedriftete Uhr, vergrößert aber auch die Menge der Codes, die ein Server akzeptieren würde, also ist es ein Kompromiss; ±1 ist die Standardbalance.
- Wofür sind die Ziffern und die Periode?
- Die Ziffern sind, wie viele Stellen der Code hat — sechs fast überall, sieben oder acht, wo ein Dienst etwas mehr Stärke will. Die Periode ist, wie viele Sekunden ein Code gültig bleibt, standardmäßig dreißig. Beide stehen in der otpauth:// URI, und beide müssen auf beiden Seiten übereinstimmen, sonst passen die Codes nicht.