Help with the calculation (and usefulness) of password entropy
这是一个由两部分组成的问题:
第1部分
首先,在PHP中计算密码的熵。我找不到任何经验性良好的代码示例,我真的希望能有助于找到计算最终数字的"正确"方法。网上很多人都有他们自己的加权算法,但我真的在寻找这个方程的科学答案。
我将使用密码熵作为一个更大的安全系统的一部分,并作为一种分析我们的整体数据安全的方法,基于可访问的信息,如果用户的密码被破坏,以及密码被暴力破解的容易程度。
第2部分
这个问题的第二部分是:这个数字到底有多有用?我的最终目标是为系统中的每个密码生成一个"分数",我们可以使用它作为动态实体来监控整个系统的安全性。对于字典攻击、L33T替换密码等,我可能需要使用另外一两种算法——但我确实认为熵在这种"整体"系统评级中起着重要作用。不过,我欢迎其他方法的建议。
我是什么Know
我已经看到一些对数方程来计算所说的熵,但我还没有看到一个好的例子,它实际上不是一个数学方程。我真的可以使用一个代码示例(即使不是严格地用PHP)让我前进。
延伸
在发表评论时,我意识到我可以更好地解释这个计算的有用性。当我在旧系统上工作时,用户的密码非常弱,我必须有一些具体的证据证明这一弱点,然后我才能提出一个理由,迫使所有用户将其密码更改为新的(强制的)强密码。通过为系统中的每个用户帐户存储密码强度分数,我可以构建几个不同的指标来显示系统的整体弱点,并为更强的密码提供理由。
蒂亚
- 我无法控制熵,但我以前成功地使用过cracklib2。有一个名为crack的Pear包用于PHP。
- 投反对票是怎么回事?如果你要标记它,请告诉我为什么我可以调整问题或分类。
- +1反对投反对票,因为这是一个很好的问题。
- -1测试同情投票的有效性。开玩笑吧。
- 哈!谢谢你平衡了下议价——也许他们只是不喜欢我在角落里的嫌疑犯。= P
字符串的熵具有此处指定的形式定义:http://en.wikipedia.org/wiki/entropy(信息论)
这个价值有多大用处?这要看情况而定。这里有一个方法(Java)来计算分配给我的熵:
1 2 3 4 5 6 7 8
| public static double entropy () {
double h = 0, p ;
for (int i = 0; i < count.size (); i ++){
p = count.get (i )/(totalChars *1.0);
h -= p *Math .log(p )/Math .log(2);
}
return h ;
} |
count是一个映射,其中(key,value)对应于(char, countForChar)。这显然意味着您必须在调用此方法之前处理字符串。
编辑2:这里有相同的方法,用PHP重写
1 2 3 4 5 6 7 8 9
| function entropy ($string) {
$h=0;
$size = strlen($string);
foreach (count_chars($string, 1) as $v) {
$p = $v/$size;
$h -= $p*log($p)/log(2);
}
return $h;
} |
编辑3:密码强度比熵大得多。熵是关于不确定性的,不一定意味着更安全。例如:
"akj@!0aj"的熵为2.5,"password"的熵为2.75。
- 感谢您的回答,但我知道熵的定义,我更感兴趣的是它的密码安全应用程序,以及如何在PHP中实现这一点。例如,我可能不想针对密码运行热力学熵算法。英雄联盟
- @谢恩-我知道。看我的编辑。
- 谢谢你的更新——我想这会有很大帮助。在您关于安全性的注释中,您是绝对正确的,这就是为什么我提到将此作为更大系统的一部分使用,以及执行字典检查等等。尽管我相信这一部分是可行的。
- 回答很好,+1!
- 值得一提的是,上述函数返回了以nats度量的数据的熵。其他计量单位包括位和禁令。Wolframalpha以位度量熵:示例1、2和3。另请参见codepad.org/ovvrkwqj。
强制一定程度的熵是CWE-521的要求。
(1) Minimum and maximum length;
(2) Require mixed character sets (alpha,numeric, special, mixed case);
(3) Do not contain user name;
(4) Expiration;
(5) No password reuse.
- @Rook——我真的很希望你能过来——你是我关于存储明文密码的另一个问题的大评论员(stackoverflow.com/questions/2283937/&hellip;),我想这就是你想要的。您能就密码度量提供进一步的建议吗?我正试图根据系统中使用的密码拼凑出一种方法来监控整个系统的安全性。我认为熵将是一个很好的开始,但对其他建议的度量也开放。
- @谢恩首先,这些规则会激怒人们,但他们会更安全。CWE-521中的规则2最好使用regex执行,这将阻止最常用的密码以及所有字典单词,因为这是可以执行的最佳规则。我不知道强制使用最大大小有什么帮助,但最大大小可以是几个KB(为什么不?)说实话,你的问题有点奇怪,熵是关于潜力的,通过强制使用混合字符集,你就增加了潜力。
- @肖恩在旁注CWE-257是非常重要的,我不知道你为什么忽视它。如果有人不知道他们的密码,那么告诉他们没有意义。如果需要更新所使用的消息摘要,可以在下次登录时进行更新。从用户的角度来看,绝对没有什么可以获得的,从攻击者的角度来看,这会使您成为一个多汁的目标。
- @Rook-我承认我有点困惑,你的第一条评论很有意义,我喜欢重新设置密码来限制字典/重复字符。但是,您的第二条评论似乎不适用于这个问题——我如何忽略CWE-257,我并不是在谈论给用户密码(不在本帖中,在另一篇(参考)帖中,我选择了一个也没有的最佳答案)。不管怎样,我使用熵位作为一个度量,我可以使用它来度量我的用户所选密码的强度——这有利于我看到用户密码强度的平均值。
- 基本上,数据库中的每一个用户行都会保存一个密码"score",我可以使用这个总体分数(有点基于熵)来衡量我的用户选择的密码的强度。这是一个现有的用户集,我不能在没有某些正当理由的情况下对其强制实施高度安全的密码要求,因此这个分数将帮助我展示我们的系统是如何(潜在)由于用户在当前(弱)要求中选择密码而变得脆弱的。
- @谢恩,好吧,我会在真实世界的攻击场景中连接这些片段。如果数据库中存储了密码强度分数,则具有SQL注入漏洞的攻击者将获得该分数。他可以选择整个系统中最弱的密码,然后首先攻击它们。这个系统应该是创建一个新密码的障碍,从而使所有密码更强大,而不是存储,因为它将被用来对付你。
- @Shane在违反CWE-257的情况下,如果攻击者知道其中一个密码,那么他就可以对您的密钥进行暴力破解。一旦这个单一的密钥被残忍地强制使用,他就会一下子解密系统上的所有密码。这就是使用消息摘要的原因,每个密码都必须分别强制执行。
- @好吧,我知道你在说什么,把他们的密码分数存储在数据库里。然而,在这个特定的实例中,如果他们进入我的数据库足够远,能够看到这个分数,那么他们就不需要密码——他们已经拥有了我100%的安全数据。但是,在我构建的其他项目中,如果其他重要项目(如上传的文档等)存在风险(不直接存储在数据库中),我将考虑您的建议。再次感谢。
- @"纵深防御"是关于失败的计划。SQL注入是一个非常常见的漏洞,它应该是构建安全应用程序时考虑的最大威胁。当您的应用程序可能被滥用并存在严重漏洞时,密码安全毫无意义。
要使用熵,您不仅需要获取单个密码的香农熵,还需要将其作为常用密码列表中的一个元素。如果一个密码与其他密码非常相似,那么它的熵将比其他密码低。如果它非常独特,它会更高。