帮助计算(和有用)密码熵

Posted

技术标签:

【中文标题】帮助计算(和有用)密码熵【英文标题】:Help with the calculation (and usefulness) of password entropy 【发布时间】:2011-03-12 23:57:13 【问题描述】:

这是一个两部分的问题:

第 1 部分

首先,处理在 php 中计算密码的熵。我一直找不到任何在经验上合理的代码示例,并且真的希望在找到计算最终数字的“正确”方法方面得到一些帮助。网上很多人都有自己自制的加权算法,但我真的在寻找方程的科学答案。

我将使用密码熵作为更大安全系统的一部分,并作为一种分析我们整体数据安全性的方法.

第 2 部分

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

我所知道的

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

扩展

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

TIA

【问题讨论】:

我无法帮助熵,但我之前成功使用过cracklib2。有一个名为 crack 的 Pear 包用于 PHP。 【参考方案1】:

字符串的熵在这里有一个正式的定义: http://en.wikipedia.org/wiki/Entropy_(information_theory)

这个值会有多大用处?这取决于。 这是一种计算我为作业所做的熵的方法(在 Java 中):

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 是一个 Map,其中 (key, value) 对应于(char, countForChar)。这显然意味着您必须在调用此方法之前处理字符串。

编辑 2:这是相同的方法,用 PHP 重写

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 中实现这一点更感兴趣。例如,我可能不想针对密码运行热力学熵算法。哈哈 感谢您的更新——我认为这将大有帮助。关于安全性,您是绝对正确的,这就是为什么我提到将其用作更大系统的一部分并进行字典检查等。对于这部分,虽然我相信它可能会起作用。 值得一提的是,上述函数返回的是nats中测量的数据的熵。其他 UOM 包括 bitsbans。 WolframAlpha 以比特为单位测量熵:例如 onetwothree。另见codepad.org/OvvRKwQj。【参考方案2】:

强制一定程度的熵是CWE-521 的要求。

(1) 最小和最大长度; (2) 要求混合字符集(字母、数字、特殊、混合大小写); (3) 不包含用户名; (4) 到期; (5) 不重复使用密码。

【讨论】:

@Rook - 我实际上有点希望你能绕过 - 你是我关于存储纯文本密码 (***.com/questions/2283937/…) 的另一个问题的重要评论者,我认为这将是正确的你的胡同。您能否就密码指标提供任何进一步的建议?我正在尝试根据系统中使用的密码拼凑一种方法来监控整体系统安全性。我认为熵是一个很好的起点,但也对其他建议的指标持开放态度。 @Shane 首先,这些规则会惹恼人们,但这样做会更安全。 CWE-521 中的第 2 条规则最好使用正则表达式来执行,这将阻止最常用的密码以及所有字典单词,因此这是可以执行的最佳规则。我看不出强制执行最大大小有什么帮助,但最大大小可能只有几 kb(为什么不呢?)。老实说,您的问题有点奇怪,熵是关于潜力的,通过实施混合字符集,您正在增加潜力。 @Shane 附带说明 CWE-257 非常重要,我不知道您为什么忽略它。如果有人不知道他们的密码,那么告诉他们是没有意义的。如果您需要更新使用的消息摘要,您可以在下次登录时进行。从用户的角度来看,绝对没有任何好处,而从攻击者的角度来看,它会让你成为一个多汁的目标。 @Shane,好的,我将在现实世界的攻击场景中连接各个部分。如果您在数据库中存储了密码强度分数,那么具有 SQL 注入漏洞的攻击者将拥有此分数。他可以挑选出整个系统中最弱的密码,然后先攻击它们。该系统应该是创建新密码的障碍,从而使所有密码更强大,而不是存储,因为它会被用来对付你。 @Shane “深度防御”是关于计划失败的。 SQL 注入是一个非常常见的漏洞,它应该是您在构建安全应用程序时考虑的最大威胁。当您的应用程序可能因严重漏洞而被滥用时,密码安全性就毫无意义。【参考方案3】:

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

【讨论】:

以上是关于帮助计算(和有用)密码熵的主要内容,如果未能解决你的问题,请参考以下文章

为什么交叉熵可以用于计算代价函数

Java ID3计算熵

Tensorflow四种交叉熵函数计算公式

两幅图像的互信息和联合熵 - MATLAB

当目标不是单热时,如何计算 Pytorch 中 2 个张量之间的正确交叉熵?

Python近似熵,样本熵,模糊熵计算高效版