如何估计密码的熵?


14

阅读有关密码强度的各种资源后,我试图创建一种算法,以粗略估计密码的熵。

我正在尝试创建一种尽可能全面的算法。此时,我只有伪代码,但是算法涵盖以下内容:

  • 密码长度
  • 重复字符
  • 模式(逻辑)
  • 不同的字符空间(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<,其中不包含任何单词或模式。


2
您看过tech.dropbox.com/?p=165吗?它可能会给您一些想法。在dl.dropbox.com/u/209/zxcvbn/test/index.html上有一个演示,代码在github上。


一个选择可能是通过压缩算法来运行他们,看看他们如何压缩,这里唯一的问题是,大多数压缩交易算法是设计工作,大量的数据,你需要一个小的数据
JK。

1
@mouviciel:我打败你了。阅读第一行:D
Wug,2012年

@Wug-太好了!我没有链接:无法想象各种各样的资源涵盖了这类研究!
mouviciel 2012年

Answers:


9

NIST SP 800-63的 p46附录A 讨论了Claude Shannon的工作,后者使用许多位来估计密码熵。确实,这是XKCD卡通用来计算熵位的文档。特别:

  • 第一个字符的熵取为4位;
  • 接下来的7个字符的熵是每个字符2位;这与Shannon的估计大致一致,即“当统计效果扩展到不超过8个字母时,则认为每个字符的熵大约为2.3位;”
  • 对于第9至20个字符,熵取为每个字符1.5位;
  • 对于21岁及以上的字符,每个字符的熵取1位;
  • 为要求同时使用大写字母和非字母字符的合成规则分配了6位熵的“加分”。这会强制使用这些字符,但是在许多情况下,这些字符只会出现在密码的开头或结尾,并且会在一定程度上减少总的搜索空间,因此好处可能不大,几乎与密码的长度无关。密码;
  • 广泛的字典检查增加了高达6位的熵奖励。如果攻击者知道字典,那么他可以避免测试这些密码,并且无论如何都将能够猜出字典的大部分内容,但是,如果没有字典规则,这将是最有可能选择的密码。假定字典测试的大多数猜测熵收益都归因于相对较短的密码,因为可以记住的任何长密码必须一定是由字典单词组成的“密码短语”,因此奖金在20时降为零。字符。

想法是,身份验证系统将选择某些熵级别作为阈值。例如,10位可能是弱的,20位是中等的,30位是强的(例如,任意选择一个数字,而不是推荐值)。不幸的是,该文档不建议使用这种阈值,可能是因为暴力破解或猜测密码的计算能力会随着时间的推移而增加:

作为强加某些特定规则的替代方案,身份验证系统可以使用上述规则为用户密码分级,并接受符合某些最低熵标准的任何密码。例如,假设需要至少具有24位熵的密码。我们可以通过观察字符串具有23个字符并满足需要大写字母和非字母字符的合成规则来计算“ IamtheCapitanofthePina4”的熵估计。

这可能是您想要的,也可能不是,但如果没有其他要求的话,这并不是一个不好的参考点。

[编辑:添加了以下内容。]

论文《通过攻击大量公开的密码来测试密码创建策略的度量标准》(作者Matt Weir,Sudhir Aggarwal,Michael Collins和Henry Stern)证明了如上所述的Shannon模型并不是人类生成的密码的准确熵模型。我建议您查看“第5节,生成新密码创建策略”,以获取更准确的建议。


3
维基百科有关密码强度的文章指出,这些规则对于人工生成的密码不正确。
Ryathal

1
正确(goo.gl/YxRk有意思的阅读)。
akton 2012年

当然有一个警告。对于统计上典型的密码(由于人们是人而倾向于遵循某些规则),它可能是相当准确的。这些准则不会考虑以下事实:随机生成的密码将以典型的长度远远超过人工生成的密码,因为它们(可能)不包含任何模式且没有单词。
乌格2012年

4

此页面底部查看KeePass的源代码。本类实现了一个相当不错的算法,这似乎是符合你正在寻找有到位。我的结果看起来像这样:QualityEstimation

aaa                              8
aaaaaaaaa                        9
abcdefghi                       18
H0ley$Mol3y_                    73
s^fU¬5ü;y34G<                   99
[a^36]*                         10
[a^20]A[a^15]*                  18
Tr0ub4dor&3                     66
correct horse battery staple    98

这会计算熵还是其他一些度量(例如bogofitness)?您还记得将[a ^ 36]扩展为'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa吗?
乌格2012年

嗯,不,我逐字复制了这些字符串:(我完全认为这是对特殊字符的巧妙使用,乍一看不是正则表达式。我会再给它一个镜头并进行更新。其次,它会计算熵,是的。
杰西C.切片机

1
它不是一个正则表达式,而是像我以前常使用的怪异记号,以避免不得不用25个字符来修饰我的表
Wug 2012年

2
我必须为“ enfatten”对该评论+1。对于这种情况,这似乎是一个完美的单词。
Jesse C. Slicer 2012年

1
实际上,它的拼写是“ KeePass”,而不是“ KeyPass”。(我自己进行编辑,但必须超过6个字符。)
Ian Dunn 2013年

1

你问

具体地说,有人能想到向算法输入密码会过高估计其强度的情况吗?

但是,您有一个问题的例子。根据设计,xkcd2的熵约为44位,但是您估计为160.5位。


因此,总的来说,当考虑单词或比其他单词更可能使用的字符组合时,该算法会崩溃。我还要指出,典型的xkcd示例不包含空格,而我的计算则包含空格。
乌格2012年

@Wug,这是一个合理的概括。zxcvbn解决了该问题,在此问题的第一条评论中提到了该问题。
彼得·泰勒

1

谁能提供一些关于此算法可能弱点的见解?具体地说,有人能想到向算法输入密码会过高估计其强度的情况吗?

您在序言中已经暗示了一些内容(字典攻击等)。本质上,攻击者可以猜测许多常见的做法,从而大大降低了搜索空间。我很确定您的算法会“高估”以下内容:

  • 到处
  • 到处
  • 到处1

密码相当长,但由于原始单词出现在基本词典中而容易被破解,并且修改被认为足够普遍以构成任何体面的词典攻击的一部分。典型的字母->数字转换(即3v3rywh3r3)也应该被认为是很弱的,因此您应该为此付出代价。

在较小程度上,其他故障密码可能是具有明显模式的密码,例如:

  • abcdefghijklmnop
  • abcde12345

尽管这些可能不太可能成为实际词典攻击的目标,但它们遭受的问题与您的“ aaaaa ...”示例类似。

我不确定大多数词典攻击中当前是否都以密码短语为目标,但是毫无疑问,随着密码短语的流行,它们将越来越受到攻击。我认为著名的xkcd示例考虑了这一点,因为每个“公用字”仅分配了11位。您的算法也会高估这些类型的密码。

因此,总而言之,该算法在估计方面做得相当不错,但实际上应该考虑密码的结构和常见的已知模式。


一级派生检查将识别所有这些模式。
乌格2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.