Sécurité des mots de passe

Sécurité des mots de passe : entropie, résistance brute-force et génération cryptographique

Sécurité des mots de passe : entropie, résistance brute-force et génération cryptographique

Les mots de passe restent un mécanisme d’authentification central dans les architectures modernes : accès SSH, consoles d’administration, bases de données, services SaaS, comptes techniques, secrets applicatifs. Malgré l’essor du MFA et des clés matérielles, la compromission par mot de passe faible demeure un vecteur d’attaque majeur. Ce cours formalise les bases techniques pour évaluer objectivement la robustesse d’un mot de passe, estimer sa résistance face à une attaque brute-force, générer des secrets cryptographiquement sûrs, et implémenter des politiques cohérentes en environnement Linux / DevOps.

Problématique terrain

Sur le terrain, les erreurs sont récurrentes :

  • Politiques basées uniquement sur la « complexité » (majuscule + chiffre + symbole).
  • Longueur minimale insuffisante (8 caractères encore courant en 2026).
  • Confiance excessive dans des patterns prévisibles : Password1!, Company2026!.
  • Mauvaise estimation des capacités réelles de calcul GPU.
  • Générateurs non cryptographiques (usage de Math.random() côté frontend).
  • Mots de passe forts mais stockés sans hash robuste.

Conséquence : un mot de passe « conforme » peut rester crackable en minutes si son espace de recherche réel est faible.

1. Entropie théorique

L’entropie mesure l’imprévisibilité d’un mot de passe en bits.

Formule :

E = L × log2(C)
  • L = longueur du mot de passe
  • C = taille du charset utilisé

Charsets standards :

CharsetTaille
Minuscules26
Majuscules26
Chiffres10
Symboles standards~32

Exemple : mot de passe de 16 caractères avec minuscules + majuscules + chiffres :

C = 26 + 26 + 10 = 62
E = 16 × log2(62) ≈ 16 × 5.95 ≈ 95 bits

95 bits d’entropie théorique représentent 295 ≈ 3.96 × 1028 combinaisons.

Seuils indicatifs :

  • 60 bits : acceptable usage standard.
  • 80 bits : recommandé production.
  • 100+ bits : très robuste.
Limite importante : L’entropie suppose une distribution uniforme et aléatoire. Un mot présent dans une wordlist ou construit selon un pattern ne respecte pas cette hypothèse — son entropie réelle est bien inférieure à l’entropie calculée.

2. Attaque brute-force

Temps théorique :

Temps ≈ (2^E) / R

E = entropie
R = tentatives/seconde

Ordres de grandeur (approximatifs) :

ScénarioVitesse
CPU seul107 – 109 /s
GPU moderne (hash faible SHA1)109 – 1011 /s
Hash lent (bcrypt/Argon2 bien configuré)103 – 105 /s

La résistance réelle dépend donc fortement de l’algorithme de hash utilisé, de son paramétrage, et de l’accès offline à la base.

3. Hashing sécurisé

Ne jamais stocker un mot de passe en clair. Algorithmes recommandés :

  • bcrypt
  • scrypt
  • Argon2id (recommandé)

Exemple Argon2id via CLI :

echo -n "MotDePasseFort" | argon2 "somesalt" -id -t 3 -m 16 -p 2

Paramètres :

  • -t : itérations (temps)
  • -m : mémoire (2m KB)
  • -p : parallélisme

Un hash lent réduit drastiquement l’efficacité des attaques offline — passer de 1010 à 104 tentatives/seconde change fondamentalement l’équation.

4. Génération cryptographique

Un générateur sécurisé doit utiliser une source d’aléa cryptographique, jamais un PRNG standard.

JavaScript moderne (navigateur / Node.js) :

// Correct
const array = new Uint32Array(1);
crypto.getRandomValues(array);

// À proscrire
Math.random(); // NON cryptographique

Linux / CLI :

# Via /dev/urandom
head -c 32 /dev/urandom | base64

# Via OpenSSL
openssl rand -base64 32
Biais modulaire : Lors de la sélection d’un caractère dans un charset via value % charset.length, si la plage de l’aléa n’est pas un multiple exact de la taille du charset, les premiers caractères sont légèrement surreprésentés. Utiliser le rejection sampling pour éliminer ce biais.

5. Passphrases

Une passphrase est une suite de mots aléatoires séparés par un délimiteur. Alternative robuste et mémorisable aux mots de passe complexes.

Si la wordlist contient 7 776 mots (Diceware classique) :

# 4 mots
E ≈ log2(7776^4) ≈ 51.7 bits

# 6 mots
E ≈ log2(7776^6) ≈ 77.5 bits

Avantages : haute mémorisation, espace de recherche massif si sélection réellement aléatoire.

Risques : wordlist faible, sélection biaisée, mot choisi manuellement plutôt qu’aléatoirement.

Exemple : correct-horse-battery-staple — mémorisable, ~51 bits d’entropie avec une wordlist de 2 048 mots.

Implémentation concrète

Politique PAM Linux

Fichier : /etc/pam.d/common-password

password requisite pam_pwquality.so retry=3 minlen=14 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1
  • minlen=14 : longueur minimale
  • ucredit=-1 : au moins 1 majuscule
  • lcredit=-1 : au moins 1 minuscule
  • dcredit=-1 : au moins 1 chiffre
  • ocredit=-1 : au moins 1 symbole
Cette approche impose la complexité mais n’impose pas l’entropie réelle. Un mot de passe comme Aaaaaaaaaaaa1! est conforme mais reste trivial.

Configuration SSH

Dans /etc/ssh/sshd_config :

PasswordAuthentication no
PubkeyAuthentication yes

Bonne pratique : désactiver totalement l’authentification par mot de passe sur serveurs exposés.

Paramétrage bcrypt (Node.js)

const bcrypt = require('bcrypt');

const saltRounds = 12;
const hash = await bcrypt.hash(password, saltRounds);

12–14 rounds recommandés selon capacité serveur. En 2026, 10 rounds devient insuffisant face aux GPU modernes.

Génération côté CLI pour service

tr -dc 'A-Za-z0-9!@#$%^&*()_+=' < /dev/urandom | head -c 32

À intégrer dans les scripts d’initialisation d’infrastructure (Terraform, Ansible, scripts de bootstrap).

Erreurs fréquentes

  • 8 caractères complexes au lieu de 16+ simples.
  • Réutilisation inter-services.
  • Hash SHA256 simple sans sel.
  • bcrypt avec 8 rounds en 2026.
  • Stockage en variable d’environnement non protégée (.env commité).
  • Générateurs maison basés sur timestamp ou UUID v4 non cryptographique.
  • Entropie théorique utilisée comme unique indicateur de robustesse.
  • Oubli de limiter les tentatives en ligne (rate limiting).

Bonnes pratiques professionnelles

  • Longueur minimale ≥ 14 caractères (humain) / ≥ 20 (machine / compte technique).
  • Favoriser la longueur plutôt que la complexité artificielle.
  • Argon2id pour le stockage des mots de passe.
  • Paramétrage mémoire significatif (> 64 MB en production si possible).
  • Rate limiting côté application et infrastructure (fail2ban, nginx limit_req).
  • MFA obligatoire pour tous les comptes à privilèges.
  • Rotation uniquement si compromission avérée (conformément NIST SP 800-63B — la rotation périodique systématique est déconseillée).
  • Gestionnaire de secrets pour comptes techniques (HashiCorp Vault, Bitwarden Secrets Manager, KeePass).
  • Audit régulier des politiques PAM et des comptes de service.
  • Désactivation de l’authentification par mot de passe SSH dès que possible.

Conclusion pragmatique

Un mot de passe robuste n’est pas défini par sa complexité visuelle mais par son espace de recherche réel et son mode de stockage.

La sécurité repose sur trois piliers :

  1. Génération réellement aléatoire.
  2. Longueur suffisante (entropie > 80 bits).
  3. Hash lent correctement paramétré côté serveur.

L’entropie est un indicateur mathématique utile, mais elle doit être interprétée avec discernement face aux attaques modernes basées sur dictionnaires, patterns et GPU. L’objectif n’est pas d’imposer des contraintes arbitraires, mais de réduire concrètement la surface d’attaque.