关于php:帮助计算(和有用性)密码熵

Help with the calculation (and usefulness) of password entropy

这是一个由两部分组成的问题:

第1部分

首先,在PHP中计算密码的熵。我找不到任何经验性良好的代码示例,我真的希望能有助于找到计算最终数字的"正确"方法。网上很多人都有他们自己的加权算法,但我真的在寻找这个方程的科学答案。

我将使用密码熵作为一个更大的安全系统的一部分,并作为一种分析我们的整体数据安全的方法,基于可访问的信息,如果用户的密码被破坏,以及密码被暴力破解的容易程度。

第2部分

这个问题的第二部分是:这个数字到底有多有用?我的最终目标是为系统中的每个密码生成一个"分数",我们可以使用它作为动态实体来监控整个系统的安全性。对于字典攻击、L33T替换密码等,我可能需要使用另外一两种算法——但我确实认为熵在这种"整体"系统评级中起着重要作用。不过,我欢迎其他方法的建议。

我是什么Know

我已经看到一些对数方程来计算所说的熵,但我还没有看到一个好的例子,它实际上不是一个数学方程。我真的可以使用一个代码示例(即使不是严格地用PHP)让我前进。

延伸

在发表评论时,我意识到我可以更好地解释这个计算的有用性。当我在旧系统上工作时,用户的密码非常弱,我必须有一些具体的证据证明这一弱点,然后我才能提出一个理由,迫使所有用户将其密码更改为新的(强制的)强密码。通过为系统中的每个用户帐户存储密码强度分数,我可以构建几个不同的指标来显示系统的整体弱点,并为更强的密码提供理由。

蒂亚


字符串的熵具有此处指定的形式定义: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。


强制一定程度的熵是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.


要使用熵,您不仅需要获取单个密码的香农熵,还需要将其作为常用密码列表中的一个元素。如果一个密码与其他密码非常相似,那么它的熵将比其他密码低。如果它非常独特,它会更高。