如何计算密码复杂度

13

有些应用程序(或网站)在您输入密码时会计算其复杂性。

它们通常会显示一个红色的条形图,当您的密码变得更长,并包含更多类别的字符(例如小写字母、大写字母、标点符号、数字)时,该条形图会变成橙色、绿色或者更绿。

如何可靠地计算密码的复杂性?

我想出了以下算法,但我担心它将Password1!评为“非常强”,而将]@feé:m评为“弱”,因为它只有7个字符。

private int GetPasswordComplexity(string password)
{
    if (password.Length <= 4)
        return 1;

    int complexity = 0;

    int digit = 0;
    int letter = 0;
    int cap = 0;
    int other = 0;

    for (int i = 0; i < password.Length; i++)
    {
            if (char.IsDigit(password[i]) && i!=password.Length-1)
            digit = 1;
        else if (char.IsLower(password[i]))
            letter = 1;
        else if (char.IsUpper(password[i]) && i!=0)
            cap = 1;
        else
            other = 1;
    }

    complexity = digit + letter + cap + other;

    if (password.Length <= 7)
        complexity = Math.Min(3, complexity);

    return complexity;
}

2
这个正在Meta上讨论 https://meta.stackoverflow.com/q/378589/3956566 - user3956566
4个回答

32
使用类似于cracklib的工具非常好,如果你能够承受检查潜在规则所需的时间。如果你只需要快速的东西 - 比如基于JavaScript的强度计算器 - 那么请考虑估计针对暴力破解所需的潜在猜测数。对于每种字符类型,更新一个基于该类型潜在字符数的倍数。因此,如果你只有数字,则倍数为10。如果只有小写字母,则乘数为26。如果两者都有,则乘数为36 - 这是指对于密码中的每个字符,暴力攻击将需要尝试多达36个不同的字符。包含大写和小写字母、数字和标点符号的密码,则乘数为10 + 26 + 26 + 32 = 94(取决于可允许的标点符号)。
为了估计暴力方法需要的最大排列数,将乘数提高到等于密码中的数字数量的幂。这给出的是使用暴力攻击破解密码所需的最大猜测次数。假设每次猜测需要一个CPU周期,并给定最快的处理器,计算在某些排列下打破密码所需的时间。例如,如果我的乘数是10,密码长度为10个字符,则我将有10,000,000,000个潜在的组合。在3GHz处理器上,这应该需要10/3 * k或3k秒(其中k是每次猜测的循环数,通常很小)。显然,这是一个弱密码。
现在,建立一些代表合理密码强度的范围。例如,如果你认为包含大写和小写字符的8个字符密码是中等强度所需的最低要求,则你的截止点将是52 ^ 8或在3GHz处理器上大约1.5年时间(假设k = 1)。如果添加数字,则截止点变为62 ^ 8或在3 GHz处理器上大约8年。接下来,你只需要跟踪所见字符类型,构建适当的乘数,根据密码长度计算预期排列,并与预定义的截止值进行比较,以确定密码的强度等级。

1
好主意。但是: 复杂度(“PasswordPassword”)= 52 ^ 17 = 1.5 ^ 10 ^ 29 复杂度(“!:^dE1”)= 94 ^ 6 = 6x10 ^ 11 现在,哪个密码更强? - Brann
这只是一个粗略的度量。你可能还想筛选最常见的密码。http://www.modernlifeisrubbish.co.uk/article/top-10-most-common-passwords http://lawprofessors.typepad.com/law_librarian_blog/2007/05/10_most_common_.html - tvanfosson
也许如果大写字母和标点符号的"价值"更高,那么得分会更高,而没有数字的普通小写字母的得分会更低(因为它们的"价值"更低)。 - alexyorke
1
这是关于 Meta 讨论的问题 https://meta.stackoverflow.com/q/378589/3956566 - user3956566

8
我建议使用cracklib来实现这个功能。

您可以在此处获取Python绑定:http://www.nongnu.org/python-crack/ - Kamil Kisiel

3
我不会仅仅在看到数字、大写字母等时设置标志,而是会为它们打分。类似于一个得分系统。普通字母计1分,数字计2分,特殊字符计3分。
现在你的总分既考虑了字符数量,也考虑了密码的组成方式。你只需划定弱密码和强密码之间的分界线。

1
特殊字符添加的熵比数字少。数字添加的熵比字符少。您应该计算熵。 - Mausy5043

1

你还应该检查一下字典。我认为苹果公司在其内置密码检查器中就是这样做的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接