Прочитавши різні ресурси про надійність пароля, я намагаюся створити алгоритм, який дасть приблизну оцінку кількості ентропії пароля.
Я намагаюся створити максимально всебічний алгоритм. На даний момент у мене є лише псевдокод, але алгоритм охоплює наступне:
- довжина пароля
- повторені символи
- шаблони (логічні)
- різні символьні пробіли (LC, UC, Numeric, Special, Extended)
- словникові атаки
Він НЕ охоплює наступне, і ДОЛЖЕН би охоплювати його добре (хоча і не ідеально):
- впорядкування (паролі можна суворо упорядкувати шляхом виведення цього алгоритму)
- шаблони (просторові)
Чи може хтось дати деяке розуміння того, до чого цей алгоритм може бути слабким? Зокрема, чи може хтось думати про ситуації, коли подача пароля в алгоритм перевершила б його силу? Заниження - це менше питання.
Алгоритм:
// 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)
Кілька входів та їх бажані та фактичні виходи entropy_bits:
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"
Алгоритм розуміє (правильно), що збільшення розміру алфавіту (навіть на одну цифру) значно зміцнює довгі паролі, як показано різницею entropy_bits для 6-го та 7-го паролів, які обидва складаються з 36 a, але 21-го другого є з великої літери. Однак вони не враховують той факт, що наявність пароля 36 a - це не дуже гарна ідея, його легко зламати за допомогою слабкого злому пароля (і той, хто дивиться його, набере це), і алгоритм цього не відображає .
Однак це відображає той факт, що xkcd1 є слабким паролем порівняно з xkcd2, незважаючи на більшу щільність складності (це навіть річ?).
Як я можу вдосконалити цей алгоритм?
Додаток 1
Атаки на словники та атаки на основі шаблону, здається, є найбільшою справою, тому я буду брати участь у їх вирішенні.
Я міг би здійснити комплексний пошук через пароль для слів зі списку слів і замінити слова на лексеми, унікальні для зображених ними слів. Слово-лексеми розглядаються як символи та мають власну систему ваги, і вони додаватимуть власні ваги до пароля. Мені знадобляться кілька нових параметрів алгоритму (я буду називати їх lw, Nw ~ = 2 ^ 11, fw ~ = .5 та rfw), і я би врахував вагу в паролі, як і будь-який інший ваги.
Цей пошук слів може бути спеціально модифікований, щоб відповідати як малі, так і великі літери, а також звичайні підстановки символів, як у E на 3. Якби я не додав зайвої ваги таким зібраним словам, алгоритм трохи занизив би їхню силу або два на слово, що гаразд. В іншому випадку загальним правилом буде для кожного не ідеального поєднання символів давати слову бонусний біт.
Тоді я міг би провести просту перевірку шаблону, наприклад пошук запусків повторних символів та похідні тести (візьміть різницю між кожним символом), які б ідентифікували такі шаблони, як 'aaaaa' та '12345', і замінили кожен виявлений шаблон на шаблон маркер, унікальний за малюнком і довжиною. Алгоритмічні параметри (конкретно, ентропія на рисунок) можна генерувати на льоту на основі шаблону.
У цей момент я б взяв довжину пароля. Кожен маркер слова та маркер візерунку вважатимуться одним символом; кожен маркер замінив би символи, які вони символічно представляли.
Я склав якесь позначення візерунка, але воно включає довжину візерунка l, порядок візерунка o та базовий елемент b. Ця інформація може бути використана для обчислення деякої довільної ваги для кожного шаблону. Я б зробив щось краще в фактичному коді.
Модифікований приклад:
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
Точна семантика того, як обчислюється ентропія за шаблонами, готується до обговорення. Я думав про щось на кшталт:
entropy(b) * l * (o + 1) // o will be either zero or one
Змінений алгоритм знайде недоліки та зменшить міцність кожного пароля в початковій таблиці, за винятком s^fU¬5ü;y34G<
, який не містить слів чи шаблонів.