Débogueur de codes TOTP / 2FA

Générez et déboguez des codes TOTP / 2FA : dérivation RFC 6238 complète, vérification par fenêtre de dérive et analyse otpauth:// — dans votre navigateur.

Temps

Saisissez un secret pour voir un code.

otpauth:// URI pour cette configuration
otpauth://totp/user%40example.com?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&period=30

Ce que sont vraiment les six chiffres

Un code TOTP — le nombre qu'une application d'authentification renouvelle toutes les trente secondes — n'est ni aléatoire ni stocké quelque part. Il est calculé, à la fois sur votre téléphone et sur le serveur, à partir de deux choses qu'ils partagent déjà : un secret configuré une fois lorsque vous avez activé l'authentification à deux facteurs, et l'heure actuelle. Comme les deux côtés peuvent le calculer indépendamment, rien n'a à circuler entre eux à la connexion ; le serveur exécute simplement le même calcul et vérifie que sa réponse correspond à la vôtre.

TOTP (RFC 6238) est une fine couche au-dessus d'un schéma plus ancien, HOTP (RFC 4226). HOTP transforme un secret et un compteur en un code ; TOTP n'est que HOTP avec le compteur fixé au nombre de pas de temps depuis l'époque Unix. C'est toute l'idée : divisez l'heure Unix actuelle par la longueur du pas (30 secondes par défaut) et passez le résultat à HOTP. Cet outil montre chaque étape de ce calcul, car lorsqu'un code ne se vérifie pas, la réponse est presque toujours visible quelque part dans la dérivation.

La dérivation, étape par étape

Cinq étapes mènent du secret et de l'heure aux chiffres que vous saisissez. L'outil imprime chacune pour que vous puissiez comparer avec votre propre implémentation :

  • Le compteur. Prenez l'heure Unix en secondes, soustrayez T0 (0 dans tout déploiement réel), divisez par la période et arrondissez vers le bas. Avec des pas de 30 secondes, tout instant dans la même demi-minute donne le même compteur, c'est pourquoi un code dure ce qu'il dure.
  • Le HMAC. Écrivez le compteur sur 8 octets big-endian et calculez HMAC(secret, compteur) avec le hachage choisi — SHA-1 pour presque toutes les applications. Cela produit un condensé de 20 octets pour SHA-1 (32 pour SHA-256, 64 pour SHA-512).
  • Le décalage. Prenez les quatre bits de poids faible du dernier octet du condensé. C'est un nombre de 0 à 15, et il indique où lire dans le condensé — troncature dynamique, pour que le même secret n'utilise pas toujours les mêmes octets.
  • La valeur de 31 bits. Lisez quatre octets à partir du décalage et masquez le bit de poids fort (pour éviter toute confusion de signe). Il reste un entier de 31 bits.
  • Le code. Prenez cet entier modulo 10^chiffres et complétez par des zéros à gauche. Six chiffres est le choix quasi universel ; sept et huit existent et sont autorisés.

Le masquage du bit de poids fort et le modulo sont les seules étapes avec perte : de nombreux condensés différents correspondent aux mêmes six chiffres, et c'est bien, car le code n'a besoin d'être difficile à deviner que pendant les trente secondes où il vit, pas unique pour toujours.

Pourquoi un code ne correspond pas — les trois causes habituelles

Une non-correspondance TOTP n'arrive jamais avec un message d'erreur ; le code est simplement faux. En pratique c'est presque toujours l'une de trois choses, et les panneaux ici sont disposés pour les distinguer :

  • Le secret a été lu dans le mauvais format. Un secret d'authentificateur est en Base32, mais les mêmes caractères lus comme du hex — ou un secret qui était en fait du hex lu comme du Base32 — produisent des octets complètement différents et un code complètement différent. Changez le sélecteur de format et voyez lequel donne le code attendu.
  • Un paramètre diffère. Le défaut écrasant est HMAC-SHA-1, 6 chiffres, une période de 30 secondes. Un serveur utilisant SHA-256, ou 8 chiffres, ou un pas de 60 secondes, sera en désaccord avec une application restée sur les valeurs par défaut. L'otpauth:// URI porte les trois, c'est pourquoi scanner un QR les obtient correctement et saisir un secret à la main souvent non.
  • Les horloges ont dérivé. TOTP suppose que les deux côtés s'accordent sur l'heure. Si l'horloge d'un téléphone avance d'une minute, son code est en avance d'une minute sur celui du serveur. C'est à cela que sert la fenêtre de dérive : vérifier un code contre les pas de part et d'autre du maintenant dit non seulement s'il correspond mais de combien l'horloge est décalée.

RFC 6238 recommande une fenêtre de validation d'au plus un pas de chaque côté — assez pour absorber le décalage d'horloge ordinaire et la course de l'instant de renouvellement, sans élargir l'espace de recherche plus que nécessaire. Cet outil utilise ±1 par défaut et vous laisse l'élargir au débogage.

Secrets, Base32 et l'otpauth:// URI

Le secret est partagé une fois, à la configuration, et tout le reste en est dérivé. Les applications d'authentification l'encodent en Base32 (RFC 4648) — l'alphabet A–Z et 2–7, qui évite les caractères faciles à confondre et survit à l'impression sous un QR. Cet outil lit le Base32 par défaut, en ignorant les espaces que les applications ajoutent pour la lisibilité et la casse, et accepte aussi le hex pour que vous puissiez reproduire les vecteurs de test de RFC 6238, dont les secrets sont donnés en octets bruts.

Le QR code que vous scannez à la configuration n'est pas magique non plus : il encode un otpauth:// URI en texte clair qui porte le secret et tous les paramètres. Collez-en un ici pour remplir les champs, ou construisez-en un depuis les champs pour déplacer une configuration entre applications :

otpauth://totp/GitHub:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=GitHub&algorithm=SHA1&digits=6&period=30

Seul le type totp est accepté. Un otpauth://hotp URI porte un compteur au lieu d'une période, et le traiter comme du TOTP produirait silencieusement des codes faux — il est donc rejeté plutôt que deviné.

Algorithme, chiffres et période

RFC 6238 autorise HMAC-SHA-1, SHA-256 ou SHA-512, de six à huit chiffres, et toute longueur de pas. En pratique le monde s'est fixé sur SHA-1, six chiffres et trente secondes, et la plupart des applications n'implémentent que cette combinaison — un serveur qui choisit autre chose doit espérer que l'application de l'utilisateur suive, et beaucoup ne le font pas. Le choix sûr pour l'interopérabilité est le choix ennuyeux.

Il vaut la peine d'aborder la question de SHA-1 directement, car l'outil de hachage de ce site marque SHA-1 comme cassé. Les deux affirmations sont vraies. SHA-1 est inutilisable pour les signatures numériques car les attaquants peuvent fabriquer des collisions — deux documents avec le même hachage. TOTP ne dépend pas de cette propriété : sa sécurité vient de la clé secrète à l'intérieur du HMAC, non de la résistance aux collisions du hachage, et HMAC-SHA-1 reste solide. Utiliser SHA-256 ici est défendable mais apporte peu, et coûte l'interopérabilité avec les applications qui ne font que du SHA-1.

Ce que cet outil protège et ne protège pas

Tout ici s'exécute dans votre navigateur. Le HMAC est calculé avec la Web Crypto API sur votre propre appareil, le même primitif que celui des outils de hachage et HMAC, et rien de ce que vous saisissez — secret, code ou otpauth URI — n'est téléversé, stocké ni journalisé. C'est une propriété du code côté client, non une promesse à croire sur parole.

Cela dit, un secret TOTP est un second facteur : quiconque le possède peut générer vos codes. Coller un secret de production dans n'importe quelle page web — celle-ci comprise — le met dans le presse-papiers et éventuellement dans l'historique du navigateur, alors traitez-le avec le même soin qu'un mot de passe, et préférez un secret jetable ou de test lorsque vous voulez seulement comprendre le mécanisme. L'outil existe pour déboguer et apprendre, non pour être l'endroit où vit votre véritable second facteur.

Questions fréquentes

Mon secret est-il envoyé à un serveur ?
Non. Le code est calculé dans votre navigateur avec la Web Crypto API, et rien de ce que vous saisissez n'est téléversé ni journalisé. Comme un secret TOTP est un second facteur, soyez tout de même prudent en collant un secret de production — il peut passer par le presse-papiers et l'historique du navigateur comme n'importe quel texte.
Pourquoi mon code ne correspond-il pas à mon application d'authentification ?
Presque toujours l'une de trois choses : le secret a été lu dans le mauvais format (Base32 vs hex), un paramètre diffère des valeurs par défaut (la plupart des applications sont SHA-1, 6 chiffres, période de 30 secondes), ou l'horloge de l'appareil a dérivé. Le panneau de dérivation isole les deux premières, et la vérification avec une fenêtre de dérive ± révèle la troisième.
Quelle est la différence entre TOTP et HOTP ?
HOTP (RFC 4226) calcule un code à partir d'un secret et d'un compteur qui s'incrémente à chaque usage. TOTP (RFC 6238) est la même construction avec le compteur fixé au nombre de pas de temps depuis l'époque Unix, si bien que le code change avec l'horloge plutôt qu'avec un appui. TOTP est ce qu'utilisent les applications d'authentification.
Pourquoi SHA-1 est-il le défaut alors qu'il est cassé ailleurs ?
SHA-1 est cassé pour les signatures car on peut construire des collisions, mais HMAC — sur lequel TOTP est construit — ne dépend pas de la résistance aux collisions ; sa sécurité repose sur la clé secrète. HMAC-SHA-1 est solide, et c'est le seul algorithme que beaucoup d'applications d'authentification implémentent, donc c'est le défaut à la fois sûr et compatible.
Puis-je figer le code à une heure précise ?
Oui. Passez l'heure de en direct à figée et saisissez un horodatage Unix. Le code reste alors statique, c'est ainsi qu'on reproduit un vecteur de test publié — RFC 6238 donne des valeurs à des heures comme 59 et 1111111109 — ou qu'on vérifie quel code était valide à un moment passé.
Quelle doit être la taille de la fenêtre de dérive ?
RFC 6238 recommande au plus un pas de chaque côté, ce que cet outil utilise par défaut. Une fenêtre plus large tolère une horloge plus décalée mais élargit aussi l'ensemble des codes qu'un serveur accepterait, c'est donc un compromis ; ±1 est l'équilibre standard.
À quoi servent les chiffres et la période ?
Les chiffres sont le nombre de chiffres du code — six presque partout, sept ou huit là où un service veut un peu plus de robustesse. La période est le nombre de secondes pendant lesquelles un code reste valide, trente par défaut. Les deux figurent dans l'otpauth:// URI, et les deux doivent correspondre des deux côtés sinon les codes ne concorderont pas.