Avendo letto varie risorse sulla forza della password sto provando a creare un algoritmo che fornisca una stima approssimativa di quanto entropia sia la password è.
Sto cercando di creare un algoritmo il più completo possibile. A questo punto ho solo uno pseudocodice, ma l'algoritmo copre quanto segue:
- lunghezza della password
- caratteri ripetuti
- modelli (logici)
- spazi di caratteri diversi (LC, UC, Numerico, Speciale, Esteso)
- attacchi di dizionario
NON copre quanto segue, e DOVREBBE coprirlo BENE (anche se non perfettamente):
- l'ordine (le password possono essere rigorosamente ordinate per output di questo algoritmo)
- pattern (spaziali)
Qualcuno può fornire alcune informazioni su ciò a cui questo algoritmo potrebbe essere debole? In particolare, qualcuno può pensare a situazioni in cui inserire una password nell'algoritmo potrebbe OVERESTIMATE la sua forza? Le sottostime sono meno di un problema.
L'algoritmo:
// 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)
Alcuni input e i loro output entropy_bits desiderati ed effettivi:
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'algoritmo realizza (correttamente) che l'aumento della dimensione dell'alfabeto (anche di una sola cifra) rafforza notevolmente le password lunghe, come mostrato dalla differenza di entropy_bits per la sesta e settima password, che consistono entrambe di 36 a, ma la seconda Il 21 a è in maiuscolo. Tuttavia, non tengono conto del fatto che avere una password di 36 a non è una buona idea, è facilmente infranto con un password cracker debole (e chiunque lo guardi digitarlo lo vedrà) e l'algoritmo non riflette quello .
Tuttavia, riflette il fatto che xkcd1 è una password debole rispetto a xkcd2, nonostante abbia una maggiore densità di complessità (è anche una cosa?).
Come posso migliorare questo algoritmo?
Addendum 1
Gli attacchi del dizionario e gli attacchi basati su pattern sembrano essere la cosa più importante, quindi mi proverò a risolverli.
Potrei eseguire una ricerca completa attraverso la password per le parole da un elenco di parole e sostituire le parole con i token univoci alle parole che rappresentano. I token di parole sarebbero quindi trattati come caratteri e avrebbero il loro sistema di pesi, e aggiungerebbero i loro pesi alla password. Avrei bisogno di alcuni nuovi parametri dell'algoritmo (li chiamerò lw, Nw ~ = 2 ^ 11, fw ~ = .5 e rfw) e modificherei il peso nella password come farei con qualsiasi altro pesi.
Questa ricerca di parole potrebbe essere appositamente modificata per corrispondere sia a lettere minuscole e maiuscole, sia a sostituzioni di caratteri comuni, come quella di E con 3. Se non aggiungo peso extra a tali parole abbinate, l'algoritmo sottovaluterebbe la loro forza di un bit o due per parola, che è OK. Altrimenti, una regola generale sarebbe, per ogni corrispondenza di caratteri non perfetta, dare alla parola un bit bonus.
Potrei quindi eseguire semplici controlli di pattern, come ricerche di esecuzioni di caratteri ripetuti e test derivati (prendere la differenza tra ogni carattere), che identificherebbe pattern come 'aaaaa' e '12345', e sostituire ogni pattern rilevato con un gettone modello, unico per il modello e la lunghezza. I parametri algoritmici (in particolare, entropia per modello) potrebbero essere generati al volo in base al modello.
A questo punto, prenderei la lunghezza della password. Ogni token di parola e token di pattern conterebbe come un carattere; ogni token sostituisce i caratteri che rappresentano simbolicamente.
Ho inventato una sorta di notazione di pattern, ma include la lunghezza del pattern l, l'ordine di pattern o e l'elemento base b. Questa informazione potrebbe essere utilizzata per calcolare un peso arbitrario per ogni modello. Farei qualcosa di meglio nel codice reale.
Esempio modificato:
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 semantica esatta di come viene calcolata l'entropia dai pattern è pronta per essere discussa. Stavo pensando qualcosa del tipo:
entropy(b) * l * (o + 1) // o will be either zero or one
L'algoritmo modificato potrebbe trovare difetti e ridurre la forza di ciascuna password nella tabella originale, ad eccezione di s^fU¬5ü;y34G<
, che non contiene parole o pattern.