Skip to content
← 1001 Widgets
N° 040 · ●●○

Strength meter

Type a password, the meter estimates how long it would take to guess it, and spots the usual traps. The right exercise to understand entropy, and why "Sunshine2024!" is not strong.

JS
What you'll learn
  • Estimate a password's entropy
  • Spot the patterns attackers test
  • Convert seconds into a readable duration
Why this language

Pourquoi une jauge de robustesse ? Les règles du type « une majuscule, un chiffre, un symbole » donnent des mots de passe comme Soleil2024!, qui tombent en quelques secondes. Ce qui compte, c'est la longueur et l'imprévisibilité.

On estime l'entropie : la longueur multipliée par le nombre de bits apportés par chaque caractère, selon les familles utilisées. Puis on la réduit quand on repère ce que les attaquants essaient en premier : les mots de passe courants, les années, les suites de clavier, les lettres répétées.

Le temps affiché suppose une attaque hors ligne à dix milliards d'essais par seconde.

Pourquoi en JavaScript simple ? Tout se calcule dans le navigateur, rien n'est envoyé. C'est une estimation pédagogique : en production, on prend une bibliothèque éprouvée comme zxcvbn.

How it works
  1. LA TAILLE DE L'ALPHABET

    Chaque famille de caractères utilisée agrandit l'ensemble des possibles.

    function alphabet(m) {
      let n = 0;
      if (/[a-z]/.test(m)) n += 26;
      if (/[A-Z]/.test(m)) n += 26;
      if (/[0-9]/.test(m)) n += 10;
      if (/[^a-zA-Z0-9]/.test(m)) n += 33;
      return n;
    }
  2. L'ENTROPIE

    En bits : chaque bit double le nombre d'essais nécessaires.

    const entropie = m => m.length * Math.log2(Math.max(alphabet(m), 1));
  3. LES MOTIFS QUI TRAHISSENT

    Les attaquants testent d'abord les mots courants, les années et les suites.

    const COURANTS = ['123456', 'motdepasse', 'azerty', 'soleil', 'bonjour'];
    function motifs(m) {
      const bas = m.toLowerCase().replace(/[0-9]+$/, '');
      const trouves = [];
      if (COURANTS.includes(bas)) trouves.push('mot de passe courant');
      if (/(19|20)\d{2}$/.test(m)) trouves.push('année à la fin');
      if (/(.)\1{2,}/.test(m)) trouves.push('caractère répété');
      if (/(1234|abcd|azer|qwer)/i.test(m)) trouves.push('suite de clavier');
      return trouves;
    }
  4. LE TEMPS POUR LE TROUVER

    En moyenne, on tombe dessus après avoir essayé la moitié des possibilités.

    const ESSAIS_PAR_SECONDE = 1e10;
    const secondes = bits => 2 ** bits / 2 / ESSAIS_PAR_SECONDE;
  5. UNE DURÉE LISIBLE

    function duree(s) {
      const unites = [['siècle', 3153600000], ['an', 31536000], ['jour', 86400], ['heure', 3600], ['minute', 60], ['seconde', 1]];
      for (const [nom, val] of unites)
        if (s >= val) { const n = Math.floor(s / val); return `${n} ${nom}${n > 1 ? 's' : ''}`; }
      return 'Instantané';
    }
Pitfalls

PIÈGE 1 : Juger sur les règles de composition

Pitfall

Mauvais : afficher « fort » dès qu'il y a une majuscule, un chiffre et un symbole. P@ssw0rd1 coche toutes les cases et figure dans toutes les listes.

Fix

Correct : mesurer la longueur et l'imprévisibilité, et pénaliser les motifs connus.

PIÈGE 2 : Envoyer le mot de passe pour le tester

Pitfall

Mauvais : appeler un serveur à chaque frappe pour vérifier la force. Le mot de passe voyage, et peut finir dans des journaux.

Fix

Correct : tout calculer dans le navigateur. Pour vérifier les fuites, l'API Have I Been Pwned n'accepte que le début d'un hachage.

PIÈGE 3 : Croire l'estimation sur parole

Pitfall

Mauvais : présenter le temps affiché comme une garantie. La vitesse d'attaque dépend du hachage utilisé par le site.

Fix

Correct : parler d'estimation, et conseiller un gestionnaire de mots de passe et la double authentification.

PERSONNALISER
  • Un générateur de phrase de passe : quatre mots tirés au hasard dans une liste française.
  • La vérification d'une fuite avec l'API Pwned Passwords et le principe de k-anonymat.
  • Une jauge qui change de libellé selon l'usage : compte bancaire ou forum.
OPTIMISATION
  • Utilisez zxcvbn-ts, qui reconnaît des dictionnaires entiers, des noms et des dates.
  • Chargez le dictionnaire seulement quand le champ reçoit le focus, avec un import dynamique.
VERS REACT

Le mot de passe est un useState, l'analyse se calcule avec useMemo.

Le bouton Voir bascule un autre état qui change type="password" en type="text".

Ne mettez jamais le mot de passe dans l'URL, ni dans un état partagé ou journalisé.

Comments
0/1000

Loading comments…

Audience measurement

With your consent, this site measures its traffic with Google Analytics and the Meta pixel, via Google Tag Manager. Nothing is loaded until you choose, and you can change your mind at any time with the "Cookies" link at the bottom of the page.