Fonctionnement 2FA TOTP

authentifiez vos utilisateurs avec Aegis

fred

Algorithme TOTP et HOTP

L'algorithme TOTP (Time-based One-Time Password) utilise le temps comme variable pour générer des codes uniques, tandis que HOTP (HMAC-based One-Time Password) se base sur un compteur incrémental. Le processus TOTP implique :

* Calcul de T = (Temps Unix actuel - T0) / X (arrondi à l'entier inférieur)
* Génération du code : TOTP = Tronquer(HMAC-SHA-1(K, T))
* K est la clé secrète partagée, T0 le temps de départ, et X l'intervalle (généralement 30 secondes)

TOTP offre des avantages par rapport à HOTP, notamment l'absence de synchronisation de compteur entre client et serveur, une durée de validité limitée des codes, et une meilleure résistance aux attaques de rejeu[1][2].
.

Outils de Génération TOTP


Pour générer des jetons TOTP, plusieurs outils sont disponibles. En ligne de commande, "oathtool" permet une génération simple avec la commande "oathtool -b --totp VOTRE_CLÉ_SECRÈTE", tandis que "totp-cli" offre des fonctionnalités plus avancées comme la gestion de comptes multiples[1].

Pour le développement web, la bibliothèque JavaScript "otplib" est compatible avec Google Authenticator et peut être utilisée côté client[2]. Le package npm "totp-generator" offre une solution légère pour la génération de jetons TOTP dans le navigateur[3].

Ces outils utilisent l'algorithme TOTP basé sur HMAC-SHA-1, générant des codes à 6-8 chiffres qui changent toutes les 30 secondes[4].

Odoo • Image et Texte

Implémentation 2FA avec Aegis

Pour intégrer l'authentification à deux facteurs (2FA) TOTP avec Aegis sur votre propre site web, vous devez implémenter le protocole TOTP côté serveur et fournir une interface pour que les utilisateurs configurent Aegis. Voici les étapes principales :

1. Générez une clé secrète unique pour chaque utilisateur lors de l'activation du 2FA.
2. Affichez cette clé sous forme de QR code que l'utilisateur peut scanner avec Aegis[1].
3. Implémentez la vérification TOTP côté serveur en utilisant une bibliothèque compatible, comme "otplib" pour JavaScript[2].
4. Lors de la connexion, demandez le code TOTP généré par Aegis en plus du mot de passe habituel[3].
5. Vérifiez le code TOTP fourni par l'utilisateur avec celui généré côté serveur.

N'oubliez pas d'offrir des options de récupération en cas de perte d'accès à l'appareil mobile, comme des codes de secours ou une procédure de réinitialisation sécurisée[4].

Génération QR pour Aegis

Pour créer un QR code "secret" à scanner par Aegis à l'aide d'un script Bash utilisant amzqr, voici un exemple concis :

```bash
#!/bin/bash
secret="otpauth://totp/MonSite:utilisateur@exemple.com?secret=JBSWY3DPEHPK3PXP&issuer=MonSite"
amzqr "$secret" -n qrcode_secret.png -d 300 -v 10
```

Ce script génère un QR code contenant une URL otpauth avec une clé secrète TOTP. L'outil amzqr est utilisé pour créer une image PNG du QR code avec une taille de 300x300 pixels et un niveau de correction d'erreur élevé. Le QR code résultant peut être scanné par Aegis pour configurer l'authentification à deux facteurs[1][2]. Il est important de noter que la clé secrète (JBSWY3DPEHPK3PXP dans cet exemple) doit être générée de manière sécurisée et unique pour chaque utilisateur dans un environnement de production.

Pour générer des jetons TOTP (Time-based One-Time Password) en ligne de commande et en JavaScript dans le navigateur, voici quelques options :

1. En ligne de commande :

**oathtool** :
C'est un outil en ligne de commande simple et efficace pour générer des jetons TOTP[8]. Voici un exemple d'utilisation :

```bash
oathtool -b --totp "VOTRE_CLÉ_SECRÈTE"
```

**totp-cli** :
C'est un outil plus complet écrit en Go qui permet de gérer des comptes TOTP[1][7]. Il offre des fonctionnalités comme l'ajout de tokens, la génération de codes, et la gestion de namespaces. Exemple d'utilisation :

```bash
totp-cli generate namespace compte
```

Voici un exemple de code Python utilisant FastAPI pour implémenter la vérification TOTP avec un formulaire de saisie d’email et de code TOTP :

from fastapi import FastAPI, Form, Request, HTTPException
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
import pyotp
import subprocess

app = FastAPI()
templates = Jinja2Templates(directory="templates")

@app.get("/", response_class=HTMLResponse)
async def email_form(request: Request):
    return templates.TemplateResponse("email_form.html", {"request": request})

@app.post("/get_secret")
async def get_secret(email: str = Form(...)):
    # Simulation de récupération du secret en sous-process
    secret = subprocess.check_output(["echo", f"SECRET_{email}"]).decode().strip()
    totp = pyotp.TOTP(secret)
    return RedirectResponse(url=f"/verify_totp?secret={secret}", status_code=303)

@app.get("/verify_totp", response_class=HTMLResponse)
async def totp_form(request: Request, secret: str):
    return templates.TemplateResponse("totp_form.html", {"request": request, "secret": secret})

@app.post("/verify_totp")
async def verify_totp(secret: str = Form(...), totp_code: str = Form(...)):
    totp = pyotp.TOTP(secret)
    if totp.verify(totp_code):
        return {"message": "Authentification réussie"}
    else:
        raise HTTPException(status_code=400, detail="Code TOTP invalide")

Ce code utilise FastAPI pour créer deux formulaires : un pour saisir l’email et un autre pour entrer le code TOTP[1][2]. La bibliothèque pyOTP est utilisée pour la vérification du code TOTP[3]. Le secret est simulé par un sous-processus, mais dans un environnement réel, il devrait être récupéré de manière sécurisée à partir d’une base de données[4]. L’authentification est validée en comparant le code saisi par l’utilisateur avec celui généré par pyOTP[5].

Pour gérer efficacement les formulaires de vérification TOTP dans FastAPI, voici les meilleures pratiques à suivre :

  1. Utilisez Jinja2Templates pour le rendu des formulaires HTML. Cela permet une séparation claire entre la logique et la présentation[1].

  2. Créez deux formulaires distincts : un pour la saisie de l’email et un autre pour la vérification du code TOTP[1].

  3. Utilisez la bibliothèque PyOTP pour générer et vérifier les codes TOTP[2][3].

  4. Stockez le secret TOTP de manière sécurisée, idéalement dans une base de données chiffrée[2].

  5. Utilisez les dépendances FastAPI (Depends) pour injecter la session de base de données dans vos routes[1].

  6. Implémentez la validation des formulaires côté serveur à l’aide de Pydantic pour une meilleure sécurité et une gestion des erreurs plus robuste[2].

  7. Utilisez des redirections (RedirectResponse) pour gérer le flux entre les différentes étapes du processus d’authentification[1].

  8. Assurez-vous de gérer correctement les erreurs, par exemple en levant des HTTPException avec des messages d’erreur appropriés[1].

  9. Pensez à implémenter des mécanismes de récupération en cas de perte d’accès à l’appareil TOTP[5].

  10. Utilisez HTTPS pour toutes les communications, en particulier lors de la transmission de données sensibles comme les secrets TOTP[5].

En suivant ces pratiques, vous pouvez créer un système de vérification TOTP sécurisé et convivial dans votre application FastAPI.

Citations:
[1] https://vincent.jousse.org/blog/fr/tech/le-guide-complet-du-debutant-avec-fastapi-partie-2/
[2] https://github.com/wpcodevo/2fa_fastapi
[3] https://github.com/vinodiOS/two-factor-auth-FastAPI
[4] https://www.univ-orleans.fr/iut-orleans/informatique/intra/tuto/django/Tuto-Django.pdf
[5] https://paheko.cloud/authentification-a-double-facteur

ANNEXE : algorithmes mathématiques

Voici les détails sur les algorithmes mathématiques utilisés par les logiciels TOTP (Time-based One-Time Password) et la différence avec HOTP (HMAC-based One-Time Password) :

  1. Algorithme TOTP :

L’algorithme TOTP fonctionne comme suit :

  1. On définit les paramètres suivants :

    • K : la clé secrète partagée
    • T0 : le temps de départ (généralement 0, correspondant à l’époque Unix)
    • X : l’intervalle de temps (généralement 30 secondes)
  2. On calcule la valeur T :
    T = (Temps Unix actuel - T0) / X
    (arrondi à l’entier inférieur)

  3. On génère le code HOTP en utilisant T comme compteur :
    TOTP = HOTP(K, T)

  4. Le code HOTP est ensuite tronqué pour obtenir un code à 6-8 chiffres.

L’algorithme mathématique principal est le suivant :

TOTP = Tronquer(HMAC-SHA-1(K, T))

Où HMAC-SHA-1 est une fonction de hachage cryptographique.

  1. Différence avec HOTP :

La principale différence entre TOTP et HOTP réside dans la manière dont le compteur est généré :

  • HOTP utilise un compteur incrémental qui doit être synchronisé entre le client et le serveur. Ce compteur est incrémenté à chaque génération de code.

  • TOTP utilise le temps comme compteur. Il calcule le nombre d’intervalles de temps écoulés depuis une date de référence (T0) pour générer le compteur T.

Formule HOTP :

HOTP = Tronquer(HMAC-SHA-1(K, C))

Où C est un compteur incrémental.

Formule TOTP :

TOTP = Tronquer(HMAC-SHA-1(K, T))

Où T est dérivé du temps actuel.

  1. Avantages de TOTP par rapport à HOTP :
  • Pas besoin de synchroniser un compteur entre le client et le serveur.
  • Les codes ont une durée de validité limitée, ce qui améliore la sécurité.
  • Moins sensible aux attaques de rejeu, car les codes expirent rapidement.

En résumé, TOTP utilise le temps comme variable pour générer des codes uniques, tandis que HOTP utilise un compteur incrémental. Cette différence rend TOTP plus pratique et sécurisé pour de nombreuses applications d’authentification à deux facteurs.

Citations:
[1] https://www.protectimus.com/blog/totp-algorithm-explained/
[2] https://en.wikipedia.org/wiki/Time-based_One-time_Password
[3] https://datatracker.ietf.org/doc/html/rfc6238
[4] https://fr.wikipedia.org/wiki/Mot_de_passe_à_usage_unique_basé_sur_le_temps
[5] https://www.hendrik-erz.de/post/understanding-totp-two-factor-authentication-eli5
[6] https://rosettacode.org/wiki/Time-based_one-time_password_algorithm
[7] https://evolabs.dev/en/blog/totp-algorithm/