Un générateur de mot de passe dans le style d'XKCD
Depuis le début de l'année, j'utilise le gestionnaire de mot de passe open-source Keepass et j'en suis très satisfait.
En général, j'utilise le générateur de mot de passe intégré pour créer des nouveaux mots de passe. Ceux-ci ont le désavantage d'être impossibles à mémoriser.
Peut-on faire mieux ? Je pense que oui, si l'objectif est de générer un mot de passe qui peut être mémorisé facilement.
Comment ? En exploitant l'idée proposée dans le XKCD ci-dessous et en l'adaptant à la langue française !
from IPython.display import Image
Image(url='https://imgs.xkcd.com/comics/password_strength.png')
Mots français¶
Pour commencer, il nous faut une liste de mots de la langue française, que l'on peut trouver ici : http://www.pallier.org/liste-de-mots-francais.html
Avec pandas
, nous pouvons facilement télécharger la liste de mot et la transformer en DataFrame
.
import pandas as pd
df = pd.read_csv('http://www.pallier.org/extra/liste.de.mots.francais.frgut.txt', header=None)
df.head()
0 | |
---|---|
0 | a |
1 | à |
2 | abaissa |
3 | abaissable |
4 | abaissables |
Une liste de mot aléatoire¶
Maintenant, nous pouvons mettre en oeuvre un algorithme de génération : tirer quatre mots au hasard et les assembler.
from numpy.random import choice
def make_password(df, n=4):
"""Generates a password by randomly selecting n words from the dataframe."""
indices = choice(df.index, size=4, replace=True)
return [item[0] for item in df.loc[indices].values.tolist()]
make_password(df)
['limettiers', 'ressentirions', 'prédisposée', 'désolidarisassions']
On peut également calculer l'entropie du mot de passe ainsi proposé (voir ici : https://crypto.stackexchange.com/questions/374/how-should-i-calculate-the-entropy-of-a-password) :
from numpy import log2
def compute_entropy_bits(df, n=4):
"""Returns bits of entropy computed using: 4 * log_2(n)
where n is the length of the list we're choosing words from."""
return n * log2(df.size)
compute_entropy_bits(df, n=4), compute_entropy_bits(df, n=5), compute_entropy_bits(df, n=10)
(73.4415195246536, 91.801899405817, 183.603798811634)
Et pourquoi pas une petite IHM ?¶
Finalement, on peut faire une petite IHM pour pour facilement générer un mot de passe de quatre mots.
from ipywidgets import Button, HBox, VBox, HTML
class GUI:
def __init__(self):
self.buttons = [Button(description='autre mot {}'.format(i)) for i in range(1, 5)]
self.reset = Button(description='nouveau')
self.passwordbox = HTML(description='mot de passe')
self.create_new_word()
def on_new_click(b):
self.create_new_word()
self.reset.on_click(on_new_click)
def on_word_click(b):
pos = [b.description for b in self.buttons].index(b.description)
self.change_word(pos=pos)
for button in self.buttons:
button.on_click(on_word_click)
def show(self):
return VBox([HBox(self.buttons + [self.reset]),
self.passwordbox])
def create_new_word(self):
self.words = make_password(df)
self.passwordbox.value = "<b>{} </b><i>{} </i><b>{} </b><i>{}</i>".format(*self.words)
def change_word(self, pos=0):
self.words[pos] = make_password(df)[pos]
self.passwordbox.value = "<b>{} </b><i>{} </i><b>{} </b><i>{}</i>".format(*self.words)
gui = GUI()
gui.show()
Et voilà, un petit outil simple qui permet de générer des mots de passe personnalisés !