2-Faktor-Authentifizierung mit TOTP

11. August 2019

Es gibt ja sinnvolle aber auch sehr schräge Passwortrichtlinien. Jedem von uns sollte klar sein, dass es nicht sinnvoll ist, ein Passwort in mehreren Diensten zu verwenden, da wenn dieser eine Dienst gehackt wird, der Angreifer so mitunter auch Zugriff auf andere Dienste bekommt. Dann sollte ein Passwort natürlich auch eine gewisse Komplexität aufweisen. Die Regel, dass ein Passwort alle x Wochen geändert werden soll, halte ich zumindest für übertrieben. In meinem Passwort-Manager befinden sich ca. 150 Passwörter. Müsste ich diese jetzt alle paar Wochen ändern, wäre ich eine Zeit lang beschäftigt. Außerdem führt dies oft dazu, dass sich Benutzer die Passwörter dann irgendwo notieren, was dem ganzen Sicherheitsgedanken eher abträglich ist.

Um seine Accounts dennoch bestmöglich abzusichern, hat sich in den letzten Jahren OTP bzw. TOTP immer stärker verbreitert. Wer die Google oder Microsoft Authenticator App kennt, der hatte (ohne es zu wissen) bereits mit TOTP (Time-based One-time Password) zu tun.

Dabei handelt es sich um eine relativ einfache Logik, die aus einem automatisch generierten Schlüssel und der Uhrzeit einen Hash bildet, wodurch eine 6 oder 8 stellige Zahl wird, die sich z.B. alle 30 Sekunden (je nach Konfiguration) ändert. Nur wenn ein Angreifer im Besitz dieses Schlüssels wäre, könnte er diese Zahl erraten. Im Zuge einer 2FA (2-Faktor-Authentifizierung) oder auch MFA (Mehrfaktor-Authentifizierung) benötigt der Benutzer jetzt nicht nur seinen Benutzer und Passwort, sondern zusätzlich noch diesen Code – also etwas das ich kenne und etwas das ich habe. Für die Generierung der Codes gibt es in den einzelnen App-Stores viele beliebige Apps – die bekanntesten sind, wie vorhin bereits erwähnt, Google und Microsoft Authenticator.

Für Entwickler ist die Implementierung auch denkbar einfach. Wer sich nicht mit der Hashlogik dahinter beschäftigen will, der kann auf fertige Bibliotheken wie z.B. otp.net setzen. Diese enthält bereits nahezu alle benötigten Funktionen:

  • Funktion zur Generierung des Schlüssels
  • Base32-Konverter
  • Validierung des Codes (inkl. Möglichkeit von Zeitfenstern)

Die Details dazu sind auf der github-Seite von otp.net beschrieben, weshalb ich hier nicht im Detail darauf eingehe.

Damit der Endanwender den generierten Schlüssel in eine Authenticator-App hinzufügen kann, wird im Normalfall auf einen QR-Code gesetzt. Dieser sollte auf dem eigenen Webserver generiert werden, damit der Schlüssel selbst nicht nach außen gelangt. Der Aufbau des QR-Code ist wie folgt:

otpauth://totp/{IDENTIFIER}?secret={SECRET}&issuer={ISSUER}

  • Identifier = der Text, der in der Authenticator-App angezeigt wird
  • Secret = Schlüssel
  • Issuer = Ersteller, wird tw. in den Apps dargestellt.

Es gibt noch mehr mögliche Parameter, aber da diese z.B. von Google-Authenticator ignoriert werden, habe ich sie nicht explizit erwähnt. Hiermit wird mit SHA1 gehasht und der Code ist standardmäßig 30 Sekunden lang gültig.

Zusätzlich ein paar Eckpunkte bei der Implementierung, die berücksichtigt werden sollten:

  • Jeder Benutzer hat einen eigenen Schlüssel!
  • Ein Code darf, wenn stimmt nur 1x verwendet werden. Ansonsten könnte, wenn dieser abgegriffen wurde, der Angreifer mit diesem auch einsteigen, wenn dies sehr zeitnah geschieht.
  • Bei mehreren Falscheingaben, sollten für eine gewisse Zeit keine Code-Validierungen mehr erlaubt sein, um Brute-Force-Attacken zu verhindern.