阅读了有关密码强度的各种资源后,我试图创建一种算法,以粗略估计密码的熵。
我正在尝试创建一种尽可能全面的算法。此时,我只有伪代码,但是算法涵盖以下内容:
- 密码长度
- 重复字符
- 模式(逻辑)
- 不同的字符空间(LC,UC,数字,特殊,扩展)
- 字典攻击
它没有涵盖以下内容,应该很好地涵盖(尽管不是很完美):
- 排序(密码可以通过此算法的输出严格排序)
- 模式(空间)
谁能提供一些关于此算法可能弱点的见解?具体地说,有人能想到向算法输入密码会过高估计其强度的情况吗?低估问题不大。
算法:
// 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"
该算法确实(正确地)意识到增加字母大小(甚至增加一位数字)会极大地增强长密码,如第6个和第7个密码的entropy_bits的差异所示,这两个密码均由36个a组成,但第二个21st a是大写。但是,他们没有考虑以下事实:拥有36个密码不是一个好主意,它很容易被弱密码破解程序破解(任何观看您键入该密码的人都会看到它),并且算法无法反映该事实。 。
但是,它的确反映了这样一个事实,即尽管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<
,其中不包含任何单词或模式。