Exkurs: 2FA und TOTP
Es gibt verschiedene Möglichkeiten sich bei einem Online-Dienst zu authentifizieren, z.B. durch
- Wissen (Benutzername und Kennwort)
- Besitz (Smartcard, Smartphone etc.)
- Biometrische Merkmale (Fingerabdruck, Gesichtserkennung etc.)
Dabei können weitere Faktoren hinzugezogen werden:
- Standort (IP-Adresse, GPS-Daten)
- Zeit (Zeitfenster)
Je nachdem wie viele Möglichkeiten miteinander kombiniert werden, spricht man von 2-, 3- oder allgemein Mehrfaktor-Authentifizierung (2FA, 3FA, MFA).
Vor- und Nachteile
Sicherheitsgewinn
- Kennworte gelten in bestimmten Bereichen heute als nicht mehr als sicher genug (Phishing, Man-in-middle, Hacking, Ausspähen, schwache Kennworte, Brute force etc.)
- Bei mehreren Diensten werden häufig gleiche Kennworte benutzt, was zum einen die Wahrscheinlichkeit erhöht, dass diese Zugangsdaten bekannt werden und der Schaden wird durch gleich mehrere gehäckte Systeme vergrößert.
Ein Angriff muss nun auf mehreren Ebenen gleichzeitig erfolgen. Das erhöht den Aufwand des Angreifers erhöht mit jedem weiten Faktor und senkt seine Erfolgswahrscheinlichkeiten stark ab
Zwar sollte man daher bei sicherheitsrelevanten Diensten vom Angebot einer 2-Faktor-Authentifizierung auf jeden Fall Gebrauch machen, dennoch müssen auch die Nachteile angesprochen werden.
Mehraufwand
Für den Nutzer
Der Anmeldevorgang wird verlängert und aufwändiger.
Verlust des 2. Faktors (z.B. Neuinstallation des Smartphones) macht Zugang unmöglich. Bestenfalls muss mit hohem Aufwand der 2. Faktor wieder hergestellt werden (Kontaktaufnahme mit Dienstbetreiber, Zurücksetzen des 2. Faktors). Dies bietet im Übrigen auch wieder Angriffsvektoren für Hacker. Daher sollte man sich jeweils einen weiteren "2. Faktor" hinterlegen (z.B. Wiederherstellung-Token, 2. Gerät mit Freischaltung, ...)
Für den Anbieter
Für den Anbieter ist der Mehraufwand zum Einen bei der Entwicklung mit entsprechenden einmaligen Kosten größer. Zum Anderen kann der Mehraufwand während des Betriebs sehr viel höher werden. Das liegt daran, das nun mehrere Faktoren verloren gehen können. Je nach Sicherheitsgrad müssen z.B. Hotlines oder schriftliche Wiederherstellungsverfahren bereitgestellt werden.
TOTP
Das in der Beispielanwendung verwendete Time-based One-Time Password TOTP- Verfahren ist kostengünstig. Es fallen keine Gebühren für SMS-Versand oder Kosten für spezielle weitere Geräte wie z.B. SmartCard o.ä. an.
Der zu verifizierende 2. Faktor, der Authentifikation-Code (TOTP-Code) ist von Schlüssel und der Zeit abhängig:
\( TOTP{-}Code = f(Key, Time) \)
Das bedeutet, das ein einmalig generierter Schlüssel auf dem Server und einem 2. Gerät (Smartphone) zur Generierung hinterlegt wird. Dieser Schlüssel wird abgelesen und von Hand oder mittels eines QR-Codes Im Klartext auf das 2. Gerät übertragen. Die Zeit muss auf beiden Geräten natürlich einigermaßen gleich sein, den der TOTP-Code wird in der Standardeinstellung alle 30 Sekunden geändert.
Das folgende UML-Aktivitätsdiagram (nach dem UML1.3-Standard) veranschaulicht die Komplexität der Anmeldung der Beispielanwendung. Dabei ist der Workflow noch unvollständig, denn die das Zurücksetzen des TOTP-Keys usw. ist noch nicht möglich:

UML1.3 - Akivitätsdiagramm für die Benutzeranmeldung mit 2FA mit TOTP
Das zweistufige Anmeldeverfahren, wird im Programmcode simpleAuthService.py im Service-Teil im durch 2 Routen repräsentiert:
Login 1. Faktor
@app.route('/auth/user/login1', methods=['POST']) #
check username and pw

{<br> "exp": 1773252794, <br> "userId": 1<br>}
Login 2. Faktor
@app.route('/auth/user/login2', methods=['POST']) #
check 2fa totp

Struktogramm: Login 2. Faktor
Erst jetzt ist JWT-Payload:
{<br> "exp": 1773253140,<br> "roleIDs": [1, 2]<br>}
Die Rollen zur Autorisierung sind jetzt enthalten.
Die beiden Stufen des Logins werden über die Route des Dashboard aufgerufen:
|
... |
Auszug: simpleAuthService
Welcher dabei von beiden Logins aufgerufen wird, hängt vom HTML-Formular ab, von dem der Aufruf der Dashboard-Route erfolgt:
<h1>Log-in</h1><br> <p class='message'>{{message}}</p> <form id="myForm" action = "/dashboard" method = "post"> <input type="hidden" name="factor" value="1_factor" > <input id='username' type = "text" name = "username" value="testUser" placeholder="Your Username"> <input id='password' type = "password" name = "password" value="testPwd" placeholder="Your Password"/> <input type="submit" name="login" class="login login-submit" value="Login"> <a class="button" href="/googleLogin">Google Login</a> </form>
Auszug: login.html
oder
<h1>Authentication Code</h1><br> <form id="myForm" action = "/dashboard" method = "post"> <input type="hidden" name="factor" value="2_factor" > <input type = "text" name = "totpCode" placeholder = "Your Authentication Code"> <input type = "submit" name = "login" class = "login login-submit" value="Login"> </form>
Auszug: checkTotp.html
Entscheidend ist dabei das "hidden input field" mit der Bezeichnung factor.