cyber / cybersecurite-fondamentale
Authentification multi-facteurs (MFA)
Explication
Ce que vous allez apprendre
- Expliquer pourquoi deux mots de passe différents ne constituent pas un vrai MFA
- Distinguer les trois familles de facteurs d'authentification (connaissance, possession, inhérence)
- Comprendre le fonctionnement du TOTP (RFC 6238) et pourquoi il est plus sûr qu'un SMS
- Expliquer en quoi WebAuthn/FIDO2 protège contre le phishing en temps réel, contrairement au TOTP
- Repérer les fonctionnalités "se souvenir de cet appareil" qui contournent silencieusement le MFA
Dans quel contexte ?
Un service RH constate qu'un compte administrateur a été utilisé pour exporter la liste complète des salaires un dimanche à 3h du matin, depuis un pays où personne de l'équipe ne se trouve. Le mot de passe était pourtant robuste : il avait simplement été volé par phishing quelques semaines plus tôt. Si un deuxième facteur (TOTP ou clé de sécurité) avait été exigé, ce vol de mot de passe seul n'aurait mené à rien.
Pourquoi un seul facteur ne suffit jamais vraiment
Même un excellent mot de passe peut fuiter : phishing, malware, réutilisation sur un site piraté. Le principe du MFA (authentification multi-facteurs) est simple : demander une preuve d'identité qui repose sur une nature différente de preuve, de sorte qu'un attaquant qui vole une seule chose ne puisse pas se connecter. C'est l'équivalent d'un coffre-fort à double clé détenue par deux personnes différentes.
Les trois familles de facteurs
Deuxième étape : les trois familles de preuves possibles. On distingue ce que je sais, ce que je possède et ce que je suis.
| Famille | Exemples | Fiabilité |
|---|---|---|
| Connaissance | Mot de passe, code PIN, question secrète | Faible seule (peut être volée par phishing) |
| Possession | Application TOTP, clé de sécurité FIDO2, SMS | Moyenne à forte (le SMS est déconseillé) |
| Inhérence | Empreinte digitale, reconnaissance faciale | Forte, mais non révocable si compromise |
Piège fréquent
Deux mots de passe différents ne forment PAS un vrai MFA : ce n'est que la même famille de preuve (la connaissance) répétée deux fois. Un vrai MFA combine toujours deux familles distinctes.
Troisième étape : comprendre le TOTP avant de voir le code. Le TOTP repose sur une idée simple. Au moment de l'activation, le serveur et l'application (Google Authenticator, Authy) se partagent un secret commun. Ensuite, toutes les 30 secondes, chacun calcule de son côté un code à partir de ce secret et de l'heure actuelle.
Quatrième étape : pourquoi ce mécanisme est plus sûr qu'un SMS. Comme les deux horloges sont synchronisées, les codes coïncident sans jamais transiter sur le réseau. Un SMS, lui, peut être intercepté ou détourné par une attaque appelée SIM swapping, c'est pour ça qu'on le déconseille aujourd'hui.
Cinquième étape : encore un cran au-dessus, WebAuthn/FIDO2. Le TOTP a quand même une faiblesse : un faux site peut vous demander le code et le réutiliser immédiatement ailleurs, c'est du phishing en temps réel. WebAuthn règle ce problème en liant cryptographiquement chaque preuve au nom de domaine exact du site visité.
Concrètement, ça veut dire quoi ? Une clé de sécurité physique refusera de signer pour un site frauduleux, même s'il est visuellement identique à l'original au pixel près. C'est aujourd'hui la meilleure protection connue contre le phishing.
Bonne pratique
Une fonctionnalité "se souvenir de cet appareil" mal conçue peut réintroduire, sans que personne ne s'en rende compte, un contournement silencieux du MFA. Limitez toujours sa durée (30 jours maximum) et exigez une ré-authentification MFA complète pour toute action sensible (changement d'email, suppression de compte).
Maintenant que l'identité de la personne est mieux vérifiée, la question suivante est différente : une fois connectée, à quoi cette personne a-t-elle réellement le droit d'accéder ? C'est le sujet de la prochaine leçon, le principe du moindre privilège.
Commandes & code
Authentification multi-facteurs (MFA)
Le MFA combine au moins deux facteurs parmi : ce que je sais (mot de passe), ce que je possède (téléphone, clé physique), ce que je suis (biométrie).
# Facteurs et exemples
Connaissance : mot de passe, code PIN, question secrète
Possession : application TOTP, clé de sécurité FIDO2/U2F, SMS (déconseillé)
Inhérence : empreinte digitale, reconnaissance faciale
# SMS OTP est déconseillé car vulnérable au SIM swapping et à l'interception SS7# Implémentation d'un TOTP (Time-based One-Time Password, RFC 6238) compatible
# Google Authenticator / Authy, avec la librairie pyotp
import pyotp
# 1. Génération du secret lors de l'activation MFA par l'utilisateur
secret = pyotp.random_base32() # à stocker chiffré côté serveur, lié au compte utilisateur
# 2. Génération de l'URL de provisioning pour le QR code affiché à l'utilisateur
totp = pyotp.TOTP(secret)
uri = totp.provisioning_uri(name="alice@example.com", issuer_name="Technologik")
# uri -> "otpauth://totp/Technologik:alice@example.com?secret=...&issuer=Technologik"
# 3. Vérification du code saisi par l'utilisateur (fenêtre de tolérance de +/- 1 période = 30s)
def verify_totp(secret: str, code: str) -> bool:
totp = pyotp.TOTP(secret)
return totp.verify(code, valid_window=1)
print(verify_totp(secret, totp.now())) # True# Codes de récupération (backup codes) à générer et hacher comme des mots de passe
import secrets
import bcrypt
def generate_backup_codes(n: int = 10) -> list[str]:
return [secrets.token_hex(5) for _ in range(n)] # ex: "a1b2c3d4e5"
def hash_backup_codes(codes: list[str]) -> list[bytes]:
return [bcrypt.hashpw(c.encode(), bcrypt.gensalt()) for c in codes]
# Chaque code n'est utilisable qu'une seule fois -> le supprimer de la liste après usage# FIDO2 / WebAuthn : standard moderne basé sur la cryptographie asymétrique
# Le navigateur/clé génère une paire de clés PAR SITE, la clé privée ne quitte jamais l'appareil
1. Le serveur envoie un "challenge" aléatoire
2. La clé de sécurité (YubiKey, Touch ID, Windows Hello) signe le challenge avec la clé privée
3. Le serveur vérifie la signature avec la clé publique stockée en base
# Avantage majeur : résistant au phishing (la signature est liée au domaine d'origine)// Extrait côté navigateur : démarrage d'une inscription WebAuthn
async function registerSecurityKey(publicKeyOptions) {
const credential = await navigator.credentials.create({
publicKey: publicKeyOptions, // challenge + rp (relying party) + user, fournis par le serveur
});
// Envoyer credential.response (attestationObject, clientDataJSON) au serveur pour vérification
return fetch("/webauthn/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
id: credential.id,
rawId: Array.from(new Uint8Array(credential.rawId)),
response: {
attestationObject: Array.from(new Uint8Array(credential.response.attestationObject)),
clientDataJSON: Array.from(new Uint8Array(credential.response.clientDataJSON)),
},
}),
});
}# Bonnes pratiques MFA en production
1. Ne jamais autoriser le contournement silencieux du MFA (bug classique: "remember this device" trop permissif)
2. Toujours proposer des codes de récupération lors de l'activation
3. Notifier l'utilisateur par email lors de toute modification des facteurs MFA
4. Prioriser WebAuthn/FIDO2 > TOTP > SMS
5. Exiger une ré-authentification MFA pour les actions sensibles (changement email, suppression compte)Résumé
- Le MFA combine connaissance, possession et inhérence.
- TOTP (RFC 6238) est simple à implémenter et largement supporté ; WebAuthn/FIDO2 est le plus résistant au phishing.
- Les codes de récupération doivent être hachés et à usage unique.
- Toute modification de la configuration MFA doit être notifiée à l'utilisateur.
Exercices pratiques
Mission : l'export de salaires du dimanche matin
Objectif : Diagnostiquer un contournement de MFA et concevoir un TOTP correctement vérifié.
Contexte
Le service RH de Technologik découvre qu'un compte administrateur a exporté la liste des salaires un dimanche à 3h du matin, depuis un pays inhabituel. Le compte a pourtant le MFA activé. L'équipe sécurité soupçonne que la fonctionnalité "se souvenir de cet appareil" a été mal configurée.