mdpgen

Il y a quelques années j’avais fait une présentation expliquant ce qui fait la qualité d’un mot de passe. L’idée était de rendre intuitif les caractéristiques jouant dans la qualité d’un mot de passe pour arriver naturellement à la conclusion qu’une phrase de passe suffisament longue est un bon mot de passe.

Dans les cas où la mémorabilité n’est pas primordiale parce qu’il est acceptable de noter de mot de passe en clair sur du papier ou un support numérique, il est utile de tout de même conserver une autre caractéristique, la capacité à le prononcer. Cela rend plus facile la dictée de mot de passe, situation dans laquelle je suppose que la plus part d’entre nous nous sommes déjà trouvé·es. C’est, je crois, la solution retenue par Free pour ses mots de passe wifi. On obtient alors des mots comme :

varuqa-sodila-lijusa-ronifu-tijipa

Construisons un petit outil, en shell évidemment, qui permet de générer ce genre de mots de passe.

Première considération, comment récupérer de l’aléatoire ? Sur la plupart des Unix1 il existe un fichier nommé /dev/random2 qui génère du contenu aléatoire. En regardant dedans on trouve ce qui semble être n’importe quoi :

$ cat /dev/random | head -n1
W½âcpF  f©£G•U½m…}   ­»ˆÕpËHvÏzª¥mØ)ÿ;’I/¿2™ÁòI=ÊCÎöH8æ×ÝÞOÈ

Les bits aléatoires générés par /dev/random peuvent être interprétés comme du texte (ce que l’on voit juste au dessus) et donc théoriquement contenir n’importe quel caractère unicode. On peut donc obtenir les lettres de l’alphabet latin si l’on supprime le reste. Pour cela on peut utiliser tr avec les options de supression et de complément :

$ cat /dev/random | tr -d -c 'a-z\n' | head -n1
geizzddenofkdznznsknnsshhfibrkoolmwiywmoloxtoteyrptafichgzlrxniweixtczwyawajatgygsrigatwmaosgfjlelinhkrnirysdq

Ici on demande à tr de tout supprimer sauf les lettres de a à z et les retour à la ligne. On termine le programme avec head en ne retenant que la première ligne.3 En imaginant que l’on souhaite créer des groupes de trois syllabes ne gardons que qui nous intéressent :

$ cat /dev/random | tr -d -c 'a-z\n' | head -n2000 | grep -Eo '([rtjqlmpdfvsn][aiou]){3}'
dirosu
dupuvo
qimuqu
qufaro
[...]

La commande grep nous permet de ne conserver que des suites de syllabes. J’ai fait le choix de retirer certaines consonnes et voyelles dont les prononciations sont trop ambigues. Au prix d’un peu de recherche je suppose qu’il est possible de vérifier la liste des syllabes aux prononciations non ambigues en français et de ne sélectionner que celles-ci mais j’ai la flemme. Il faut également grandement agrandir le nombre de ligne que l’on récupère (l’optin -n de head) pour garantir d’avoir4 assez de données pour générer au moins un triplet de syllabe convenable.

A partir de là on peut créer des groupes de triplets avec paste. Pour créer des groupes de cinq :

$ cat /dev/random | tr -d -c 'a-z\n' | head -n2000 | grep -Eo '([rtjqlmpdfvsn][aiou]){3}' |
    head -n5 | paste - - - - - -d'-'
ripupo-tudiqo-lanoti-niludi-lovila

Voilà notre mot de passe ! Et si l’on voulait modifier la commande pour qu’elle puisse en générer autant que l’on souhaite on pourrait adapter le nombre de lignes filtrées dans les deux head avec une variable :

$ cat /dev/random |
    tr -d -c 'a-z\n' |
    head -c $((2000*$nb)) |
    grep -Eo '([rtjqlmpdfvsn][aiou]){3}' |
    head -n$((5*$nb)) |
    paste - - - - - -d'-'

Modifier le nombre de groupes de syllabes de cinq vers autre chose pourrait se faire en pré-générant les arguments passés à paste et en ajustant de nombre de groupes récupérés par le seconde head :

$ pastearg=$(yes '-' | head -n$len | paste -s -d' ')
  cat /dev/random |
    tr -d -c 'a-z\n' |
    head -c $((2000*$nb)) |
    grep -Eo '([rtjqlmpdfvsn][aiou]){3}' |
    head -n$(($len*$nb)) |
    paste $pastearg -d'-'

Ce code embarqué dans un script est dans le dépôt git http://git.bebou.netlib.re/mdpgen/log.html.

Et la sécurité dans tout ça ? Avec les syllabes retenues dans ce code la taille de notre alphabet est de 12*4 = 48. Pour avoir une entropie équivalente à une phrase de passe diceware de sept mots il faut au moins 17 syllabes donc six groupes de trois syllabes. Selon le modèle de menace cinq groupes peut être suffisant.

diceware 7 mots: 7776^7
1720618914350498356204193953
mdpgen 5 goupes: 48^(5*3)
16543163447903718821855232
mdpgen 6 goupes: 48^(6*3)
1829541532030568071946613817344

  1. mais attention, je ne sais pas à quel point c’est portable pour autant 

  2. j’utilise /dev/random non pas parce que je pense que c’est plus sécurisé mais parce que je crois bien que c’est + portable. 

  3. On pourrait demander à tr de supprimer aussi les retour à la ligne et de terminer le pipe avec un head -c plutôt qu’un head -n mais à l’usage j’ai remarqué que c’était plus lent. 

  4. ou plutôt “rendre très improbable de ne pas avoir”