URL: https://linuxfr.org/users/gouttegd/journaux/scorepw-un-evaluateur-de-mots-de-passe Title: Scorepw, un évaluateur de mots de passe Authors: gouttegd Date: 2018年01月03日T15:00:52+01:00 License: CC By-SA Tags: Score: 34 Un petit journal promotionnel pour annoncer mon dernier projet libre (qui ne devait initialement être qu’un petit de bout de code jamais supposé sortir de chez moi...) : _scorepw_, un outil permettant d’évaluer la « qualité » d’un mot de passe. Pour ceux que la théorie intéresse, je les déçois immédiatement : il n’y a rien de novateur dans _scorepw_ — pas de nouvelle méthode d’évaluation révolutionnaire à laquelle personne n’aurait encore jamais pensé. Au contraire, _scorepw_ n’est qu’un peu d’enrobage autour de bibliothèques d’évaluation de mots de passe déjà existantes et bien connues. J’invite donc ceux que la théorie derrière l’évaluation de mots de passe intéresse à se tourner vers les bibliothèques en question : * [Pwquality](https://github.com/libpwquality/libpwquality) ; * [Zxcvbn-C](https://github.com/tsyrogit/zxcvbn-c) ; * [Zxcvbn-CPP](https://github.com/rianhunter/zxcvbn-cpp). Les deux dernières sont deux implémentations différentes, respectivement en C et en C++ comme leur nom l’indique, de [Zxcvbn](https://github.com/dropbox/zxcvbn), une bibliothèque CoffeeScript notamment utilisée pour propulser l’évaluateur de mots de passe de Dropbox et présentée lors du [25^(eme) USENIX Security Symposium](https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/wheeler) en 2016. Cette bibliothèque a été ré-implémentée en de nombreux langages depuis, la page Github précédente donne la liste des implémentations disponibles. Cela étant dit, qu’est-ce donc que _scorepw_ ? Fondamentalement, c’est juste une interface en ligne de commande pour les bibliothèques ci-dessus. J’ai commis _scorepw_ pour essentiellement deux raisons : * il n’y avait à ma connaissance pas d’outil permettant l’utilisation de l’algorithme de Zxcvbn directement depuis la ligne de commande (il y a bien [des outils en ligne tout court](https://lowe.github.io/tryzxcvbn/), mais pas en ligne _de commande_) ; * il y a bien un outil _pwscore_ permettant d’appeler libpwquality depuis la ligne de commande, mais il ne donne rien de plus qu’un score de 0 à 100 sans plus de détails (alors que Zxcvbn fournit une estimation du temps requis pour craquer le mot de passe, ce que je trouve assez cool) ; * c’était la fin des vacances et je m’ennuyais. La principale caractéristique, et à mon sens le principal intérêt, de _scorepw_ est donc qu’il permet d’évaluer un mot de passe donné en utilisant _plusieurs_ bibliothèques d’évaluation (ci-après appelées des _estimateurs_), permettant d’avoir plusieurs points de vue sur la qualité du mot de passe (contrairement à _pwscore_ qui ne donne que l’évaluation de libpwquality). Pour l’instant, _scorepw_ utilise comme estimateurs les trois bibliothèques citées plus haut. J’ajouterai éventuellement d’autres bibliothèques du même genre à mesure que je les trouve. ## Utilisation _Scorepw_ prend le mot de passe à analyser en tant que seul argument positionnel sur la ligne de commande, ou le lit depuis son entrée standard en l’absence d’un tel argument. Par défaut, il utilise un seul estimateur (Zxcvbn-C) et sort simplement le score, de 0 à 100, donné par cet estimateur : ```sh $ scorepw correcthorsebatterystaple 100 ``` L’option `-e` permet de spécifier le ou les estimateurs à utiliser (ici Zxcvbn-CPP et libpwquality): ```sh $ scorepw -e zxcvbncpp,pwquality correcthorsebatterystaple Zxcvbn-CPP: 100 Pwquality: 100 ``` L’option `-a` (`--all`) est un raccourci pour `-e zxcvbn,zxcvbncpp,pwquality`, c’est-à-dire que tous les estimateurs disponibles sont sollicités : ```sh $ scorepw -a 'tr0ub4dour&3' Zxcvbn: 75 Zxcvbn-CPP: 50 Pwquality: 87 ```> On voit ici l’intérêt qu’il peut y avoir à ne pas se contenter d’un seul estimateur : le mot de passe est presque parfait pour Pwquality alors qu’il est « bof-bof » pour Zxcvbn-CPP...>> Même Zxcvbn-C et Zxcvbn-CPP, qui sont en principe deux implémentations différentes du même algorithme au départ, donnent des résultats parfois très divergents. D’après mes tests, Zxcvbn-CPP donne régulièrement des résultats plus proches de ceux obtenus avec la Zxcvbn originale (celle en CoffeeScript). D’ailleurs, le développeur de Zxcvbn-C ne cache pas qu’il a fait des choix différents et que son implémentation se comporte différemment. Enfin, l’option `-f` permet d’obtenir plus de détails sur le mot de passe analysé (avec les estimateurs qui le supportent, c’est-à-dire pas Pwquality) : ```sh $ scorepw -af 'tr0ub4dour&3' Estimator: Zxcvbn Score: 75 Entropy: 28.951 Guesses: 5.18873e+08 Attack times: Online throttled attack (100/h) ...........: centuries Online unthrottled attack (10/s) ..........: one year Offline attack with slow hashing (10k/s) ..: 14 hours Offline attack with fast hashing (10G/s) ..: less than one second Estimator: Zxcvbn-CPP Score: 50 Entropy: 23.185 Guesses: 9.534e+06 Attack times: Online throttled attack (100/h) ...........: 10 years Online unthrottled attack (10/s) ..........: 11 days Offline attack with slow hashing (10k/s) ..: 15 minutes Offline attack with fast hashing (10G/s) ..: less than one second Estimator: Pwquality Score: 87 ``` ## Problèmes connus ### De l’importance du dictionnaire Les trois bibliothèques utilisées vérifient toutes la présence du mot de passe dans un dictionnaire (y compris sous une forme modifiée). Dans l’exemple ci-dessus, 'tr0ub4dour&3' se voit attribuer un score de seulement 50 par Zxcvbn-CPP, parce que la bibliothèque a correctement reconnu (après « dé-leetification ») le mot _troubadour_. Mais 'tr0ub4dor&3', pourtant plus court d’un caractère, est considéré comme bien meilleur, cette orthographe n’étant pas dans le dictionnaire : ```sh $ scorepw -fe zxcvbncpp 'tr0ub4dor&3' Score: 100 Entropy: 36.541 Guesses: 1e+11 Attack times: Online throttled attack (100/h) ...........: centuries Online unthrottled attack (10/s) ..........: centuries Offline attack with slow hashing (10k/s) ..: 3 months Offline attack with fast hashing (10G/s) ..: 10 seconds ``` Le choix et le contenu du dictionnaire n’est donc pas anodin. Zxcvbn-C et Zxcvbn-CPP utilisent un dictionnaire constitué des mots extraits de la Wikipédia anglophone, d’une compilation de prénoms usuels, d’une compilation ([réalisée par les contributeurs de Wiktionary](https://en.wiktionary.org/wiki/Wiktionary:Frequency_lists#TV_and_movie_scripts) des mots les plus usités dans les scripts des films et séries TV américaines, et d’une [compilation de mots de passe réels](https://xato.net/today-i-am-releasing-ten-million-passwords-b6278bbe7495) publiée par Mark Burnett (le chercheur en sécurité, pas le producteur TV). Pwquality, de son côté, utilise le dictionnaire fourni par la bibliothèque [cracklib](https://github.com/cracklib/cracklib). Ce dictionnaire est par défaut assez modeste (pour des raisons de licence), mais un dictionnaire plus conséquent peut être choisi lors de la compilation de la bibliothèque. Pour l’instant, _scorepw_ ne permet pas d’utiliser autre chose que les dictionnaires ci-dessus, qui sont directement inclus dans les bibliothèques. Une des premières pistes d’amélioration du programme serait de permettre à l’utilisateur de spécifier le ou les dictionnaires de son choix. ### Mots de passe non-ASCII La présence de caractères non-ASCII dans le mot de passe provoque parfois des résultats qui laissent pour le moins à désirer. Signalons déjà un gros bug dans Zxcvbn-CPP, qui se retrouve tout simplement bloqué dans ce qui semble être une boucle infinie dès qu’on lui demande d’analyser un mot de passe non-ASCII ! Chose amusante, le bug ne se produit que si la bibliothèque est compilé en mode _debug_, la fonction fautive n’étant appelée que dans un _assert_. Je vais essayer d’isoler plus précisément le bug avant de le remonter au développeur de Zxcvbn-CPP. Zxcvbn-C n’a pas ce problème, mais en revanche la présence d’un seul caractère non-ASCII suffit à lui faire croire que le mot de passe est très robuste : ```sh $ scorepw -f -e zxcvbn aeiouy Score: 25 Entropy: 14.208 Guesses: 18928 Attack times: Online throttled attack (100/h) ...........: 7 days Online unthrottled attack (10/s) ..........: 31 minutes Offline attack with slow hashing (10k/s) ..: one second Offline attack with fast hashing (10G/s) ..: less than one second $ scorepw -f -e zxcvbn aéiouy Score: 100 Entropy: 42.386 Guesses: 5.74881e+12 Attack times: Online throttled attack (100/h) ...........: centuries Online unthrottled attack (10/s) ..........: centuries Offline attack with slow hashing (10k/s) ..: 18 years Offline attack with fast hashing (10G/s) ..: 9 minutes ``` ## Show me the code Voilà, si vous êtes intéressés : * [la page du projet](https://incenp.org/dvlpt/scorepw.html) ; * [le repository correspondant](https://incenp.org/gitweb/?p=scorepw.git;a=summary) ; * l’[archive de la version 0.1.0](https://incenp.org/files/softs/scorepw/0.1/scorepw-0.1.0.tar.gz).