Le TOTP : la preuve qu’une sécurité de grade bancaire peut être simple : un secret partagé, une horloge synchronisée et un peu de mathématiques (HMAC).

RFC 6238. C’est le numéro de la norme que AWS utilise pour votre MFA, et c’est exactement ce qui tourne sur l’une de mes serveur ce matin. La différence entre la sécurité ‘bank-grade’ et votre project ? Aucune, si vous savez ce que vous faites.

Le système repose sur une symétrie d’information : le serveur et l’application mobile (Google Authenticator ou autre) connaissent la même chose au même moment, sans jamais avoir à se parler après la configuration initiale.

  • Offline complet : Votre téléphone n’a pas besoin d’Internet, juste d’une horloge correcte
  • Zéro coût opérationnel : Pas de SMS à payer, pas de serveurs SMTP à configurer, pas de rate limiting à gérer chez un tiers
  • Sécurité temporelle : Le code change toutes les 30 secondes. Même intercepté, il devient inutile presque instantanément (attaques replay impossible)
  • Standard ouvert : N’importe quelle app (Google Authenticator, Authy, Microsoft Authenticator, Aegis) peut lire votre QR Code car il suit le format otpauth://totp/...

1. Les 3 piliers du TOTP

A. Le Secret Partagé (The Seed)

Lors de l’étape de setup, le serveur génère une clé aléatoire (ex: JBSWY3DPEHPK3PXP). C’est ce qu’on appelle la « Seed ».

  • Elle est encodée en Base32 (pour être facile à lire et à taper si le QR code ne marche pas).
  • C’est la seule information qui doit être transférée du serveur vers le mobile une seule fois.

B. Le Temps (The Counter)

Au lieu d’un compteur incrémental (comme dans le HOTP), le TOTP utilise l’heure Unix actuelle.

  • On divise le temps par une fenêtre (généralement 30 secondes).
  • T = (Current Unix Time - 0) / 30.
  • Cela signifie que toutes les 30 secondes, le « compteur » change de valeur.

C. L’Algorithme de Hachage (HMAC-SHA1)

C’est le moteur : on mélange le Secret et le Temps via une fonction de hachage sécurisée pour obtenir une empreinte numérique unique.


2. Alors Le Processus de Génération le voici

Ce qui se passe dans le téléphone toutes les 30 secondes :

  1. Input : Le Secret (K) et le Temps actuel (T).
  2. Hachage : On calcule HMAC-SHA1(K, T). On obtient un résultat de 20 octets.
  3. Troncation Dynamique : On ne peut pas demander à l’utilisateur de taper 20 octets ! L’algorithme extrait donc 4 octets spécifiques du hachage.
  4. Conversion : Ces 4 octets sont convertis en un nombre entier.
  5. Modulo : On applique un modulo 1,000,000 pour obtenir exactement 6 chiffres.

Résultat : Le code « 123 456 » s’affiche !


3. Pourquoi c’est top pour moi ?

  • Offline : Votre téléphone n’a pas besoin d’Internet pour générer le code. Il a juste besoin d’avoir l’heure à peu près correcte.
  • Zéro Coût : Pas de SMS à payer, pas de serveurs SMTP à configurer.
  • Sécurité : Le code change toutes les 30 secondes. Même si un hacker intercepte un code, il devient inutile presque instantanément.
  • Standardisé : N’importe quelle application (Google Authenticator, Authy, Microsoft Authenticator) peut lire votre QR Code car il suit le format otpauth://totp/....

4. Focus sur l’implémentation Java

Dans mon projet, j’ai utilisé la bibliothèque dev.samstevens.totp

// 1. Génération du Secret (Dans MfaService)
SecretGenerator generator = new DefaultSecretGenerator();
String secret = generator.generate(); // Crée la Seed Base32

// 2. Création du QR Code
QrData data = new QrData.Builder()
   .label(userEmail)
   .issuer("MonAPP")
   .secret(secret)
   .build();
// On transforme ça en image Base64 (Data URI) pour le Frontend

// 3. Vérification (Dans AuthService)
CodeVerifier verifier = new DefaultCodeVerifier(new DefaultCodeGenerator(), new SystemTimeProvider());
boolean isValid = verifier.isValidCode(userSecret, codeSaisi);