Après avoir lu diverses ressources sur la force des mots de passe, j'essaie de créer un algorithme qui fournira une estimation approximative de la quantité d'entropie d'un mot de passe.
J'essaie de créer un algorithme aussi complet que possible. À ce stade, je n'ai qu'un pseudocode, mais l'algorithme couvre les éléments suivants:
- longueur du mot de passe
- caractères répétés
- modèles (logique)
- différents espaces de caractères (LC, UC, numérique, spécial, étendu)
- attaques par dictionnaire
Il ne couvre PAS les éléments suivants, et DEVRAIT le couvrir BIEN (mais pas parfaitement):
- ordre (les mots de passe peuvent être strictement ordonnés par la sortie de cet algorithme)
- motifs (spatiaux)
Quelqu'un peut-il donner un aperçu de la faiblesse de cet algorithme? Plus précisément, quelqu'un peut-il penser à des situations où le fait de fournir un mot de passe à l'algorithme surestimerait sa force? Les sous-estimations sont moins problématiques.
L'algorithme:
// the password to test
password = ?
length = length(password)
// unique character counts from password (duplicates discarded)
uqlca = number of unique lowercase alphabetic characters in password
uquca = number of uppercase alphabetic characters
uqd = number of unique digits
uqsp = number of unique special characters (anything with a key on the keyboard)
uqxc = number of unique special special characters (alt codes, extended-ascii stuff)
// algorithm parameters, total sizes of alphabet spaces
Nlca = total possible number of lowercase letters (26)
Nuca = total uppercase letters (26)
Nd = total digits (10)
Nsp = total special characters (32 or something)
Nxc = total extended ascii characters that dont fit into other categorys (idk, 50?)
// algorithm parameters, pw strength growth rates as percentages (per character)
flca = entropy growth factor for lowercase letters (.25 is probably a good value)
fuca = EGF for uppercase letters (.4 is probably good)
fd = EGF for digits (.4 is probably good)
fsp = EGF for special chars (.5 is probably good)
fxc = EGF for extended ascii chars (.75 is probably good)
// repetition factors. few unique letters == low factor, many unique == high
rflca = (1 - (1 - flca) ^ uqlca)
rfuca = (1 - (1 - fuca) ^ uquca)
rfd = (1 - (1 - fd ) ^ uqd )
rfsp = (1 - (1 - fsp ) ^ uqsp )
rfxc = (1 - (1 - fxc ) ^ uqxc )
// digit strengths
strength =
( rflca * Nlca +
rfuca * Nuca +
rfd * Nd +
rfsp * Nsp +
rfxc * Nxc ) ^ length
entropybits = log_base_2(strength)
Quelques entrées et leurs sorties entropy_bits souhaitées et réelles:
INPUT DESIRED ACTUAL
aaa very pathetic 8.1
aaaaaaaaa pathetic 24.7
abcdefghi weak 31.2
H0ley$Mol3y_ strong 72.2
s^fU¬5ü;y34G< wtf 88.9
[a^36]* pathetic 97.2
[a^20]A[a^15]* strong 146.8
xkcd1** medium 79.3
xkcd2** wtf 160.5
* these 2 passwords use shortened notation, where [a^N] expands to N a's.
** xkcd1 = "Tr0ub4dor&3", xkcd2 = "correct horse battery staple"
L'algorithme se rend compte (correctement) que l'augmentation de la taille de l'alphabet (même d'un chiffre) renforce considérablement les mots de passe longs, comme le montre la différence d'entropie_bits pour les 6e et 7e mots de passe, qui consistent tous deux en 36 a, mais le 21e du second est capitalisé. Cependant, ils ne tiennent pas compte du fait qu'avoir un mot de passe de 36 a n'est pas une bonne idée, il est facilement cassé avec un pirate de mot de passe faible (et toute personne qui vous regarde taper le verra) et l'algorithme ne reflète pas cela .
Il reflète cependant le fait que xkcd1 est un mot de passe faible par rapport à xkcd2, malgré une densité de complexité plus élevée (est-ce même une chose?).
Comment puis-je améliorer cet algorithme?
Addendum 1
Les attaques par dictionnaire et les attaques basées sur des modèles semblent être la grande chose, donc je vais essayer de les résoudre.
Je pourrais effectuer une recherche complète par le mot de passe des mots d'une liste de mots et remplacer les mots par des jetons uniques aux mots qu'ils représentent. Les jetons de mots seraient alors traités comme des caractères et auraient leur propre système de poids, et ajouteraient leurs propres poids au mot de passe. J'aurais besoin de quelques nouveaux paramètres d'algorithme (je les appellerai lw, Nw ~ = 2 ^ 11, fw ~ = .5 et rfw) et je prendrais en compte le poids dans le mot de passe comme je le ferais pour n'importe quel autre poids.
Cette recherche de mots pourrait être spécialement modifiée pour correspondre à la fois aux lettres minuscules et majuscules ainsi qu'aux substitutions de caractères courantes, comme celle de E avec 3. Si je n'ajoutais pas de poids supplémentaire à ces mots correspondants, l'algorithme sous-estimerait un peu leur force ou deux par mot, ce qui est OK. Sinon, une règle générale serait, pour chaque correspondance de caractère non parfaite, donner au mot un bit bonus.
Je pourrais ensuite effectuer des vérifications de modèle simples, telles que des recherches de séries de caractères répétés et des tests dérivés (prendre la différence entre chaque caractère), qui identifieraient des modèles tels que 'aaaaa' et '12345', et remplacer chaque modèle détecté par un modèle jeton, unique au motif et à la longueur. Les paramètres algorithmiques (en particulier, l'entropie par motif) pourraient être générés à la volée en fonction du motif.
À ce stade, je prendrais la longueur du mot de passe. Chaque jeton de mot et jeton de motif compterait comme un caractère; chaque jeton remplacerait les caractères qu'ils représentaient symboliquement.
J'ai créé une sorte de notation de modèle, mais elle comprend la longueur du modèle l, l'ordre des modèles o et l'élément de base b. Ces informations pourraient être utilisées pour calculer un poids arbitraire pour chaque modèle. Je ferais quelque chose de mieux dans le code réel.
Exemple modifié:
Password: 1234kitty$$$$$herpderp
Tokenized: 1 2 3 4 k i t t y $ $ $ $ $ h e r p d e r p
Words Filtered: 1 2 3 4 @W5783 $ $ $ $ $ @W9001 @W9002
Patterns Filtered: @P[l=4,o=1,b='1'] @W5783 @P[l=5,o=0,b='$'] @W9001 @W9002
Breakdown: 3 small, unique words and 2 patterns
Entropy: about 45 bits, as per modified algorithm
Password: correcthorsebatterystaple
Tokenized: c o r r e c t h o r s e b a t t e r y s t a p l e
Words Filtered: @W6783 @W7923 @W1535 @W2285
Breakdown: 4 small, unique words and no patterns
Entropy: 43 bits, as per modified algorithm
La sémantique exacte de la façon dont l'entropie est calculée à partir des modèles est à discuter. Je pensais à quelque chose comme:
entropy(b) * l * (o + 1) // o will be either zero or one
L'algorithme modifié trouverait des défauts et réduirait la force de chaque mot de passe dans le tableau d'origine, à l'exception de s^fU¬5ü;y34G<
, qui ne contient aucun mot ni motif.