TOTP

Hachage et signature (HMAC)

Comment signer un message ?

Signature asymétrique

Alice peut chiffrer son message avec sa clé privée. Bob pourra le déchiffrer avec sa clé publique.

Cette solution est fonctionnelle, mais le chiffrement asymétrique coûte cher.

Au lieu de ça, Alice peut simplement signer un hash de son message, qu'elle diffusera.

Signature symétrique

Le même système pourrait exister en symétrique:

Cependant, au lieu d'employer un algorithme de chiffrement symétrique, on peut directement utiliser une fonction de hachage qui utilise le secret:

Ici, le hash calculé serait par exemple hash(secret + message), où + désigne la concaténation.

Les approches suivantes:

  • hash(secret + message)
  • hash(message + secret)
  • hash(secret1 + message + secret2)

Sont (plus ou moins) vulnérables à des variantes d'attaques par extension de longueur

HMAC

L'algorithme HMAC permet de calculer un hash avec une clé, en évitant ces vulnérabilités.

En simplifiant, HMAC calcule hash(K1 + hash(K2 + message)), où K1 et K2 sont basés sur le secret fourni.

HMAC s'appuie sur des algorithmes existants, comme SHA-1 ou SHA-256.

En Python, on peut par exemple faire:

import hmac

secret = b"clé secrète"
message = b"message à signer"

hash = hmac.new(secret, message, "sha1")
print(hash.hexdigest())

Cas d'utilisation

HMAC est utilisé dans de plusieurs protocoles, comme par exemple:

  • Les JSON Web Token (JWT)
    • Permet de signer des données JSON
  • Les mots de passe à usage unique (TOTP)
    • Permet de générer des mots de passe temporaire

Mots de passe à usage unique (HOTP)

Présentation

Comment, à partir de HMAC, générer un mot de passe à usage unique ?

Idée: en partageant un secret et en utilisant un compteur, on peut générer un mot de passe qui ne sera valable qu'une seule fois. Pour cela, on peut calculer HMAC(secret, compteur).

Le compteur sera changé à chaque utilisation (dans la partie suivante, nous parlerons de TOTP, qui utilise le temps UNIX comme compteur).

On appelle ce système HOTP, pour HMAC-based One-time Password algorithm.

Fonctionnement

  1. HOTP calcule tout d'abord hash = HMAC(secret, compteur), le hash HMAC du secret et du compteur.
  2. Ensuite, les 4 derniers bits sont utilisés pour extraire un nombre entre 0 et 15. Ce nombre est utilisé comme indice pour extraire un entier de 32 bits du hash.
  3. On retire le bit de signe
  4. On prend le modulo de cet entier par 10^6, pour obtenir un nombre à 6 chiffres.

Mots de passe temporels à usage unique (TOTP)

Fonctionnement

TOTP est construit par dessus HOTP, en utilisant comme compteur le temps UNIX.

Pour rappel, le temps UNIX est le nombre de secondes écoulées depuis le 1er janvier 1970. En Python, on peut obtenir le temps UNIX avec time.time().

Plus précisément, le temps UNIX est divisé par une durée (par exemple 30 secondes), afin d'obtenir un nombre entier qui sera utilisé comme compteur.

URL

Il est possible de représenter un TOTP par une URL sous la forme suivante:

otpauth://totp/username?secret=base32secret&issuer=issuer

Où:

  • username est le nom de l'utilisateur
  • base32secret est le secret partagé, encodé en base32
  • issuer est l'entité qui a généré le TOTP

Cette URL peut être placée dans un QR code, pour faciliter l'ajout du TOTP dans une application d'authentification.