检查密码强度的最佳方法是什么?

时间:2020-03-05 18:56:40  来源:igfitidea点击:

另请参阅如何计算密码复杂度?

确保用户提供的密码是注册或者更改密码表格中的强密码的最佳方法是什么?

编辑:我有一个想法(在python中)

def validate_password(passwd):
    conditions_met = 0
    conditions_total = 3
    if len(passwd) >= 6: 
        if passwd.lower() != passwd: conditions_met += 1
        if len([x for x in passwd if x.isdigit()]) > 0: conditions_met += 1
        if len([x for x in passwd if not x.isalnum()]) > 0: conditions_met += 1
    result = False
    print conditions_met
    if conditions_met >= 2: result = True
    return result

解决方案

回答

如果有时间,请对它运行密码破解程序。

回答

http://webtecker.com/2008/03/26/collection-of-password-strength-scripts/

回答

有一个免费的开放式Ripper密码破解器,它是检查现有密码数据库的好方法。

回答

密码强度检查器,以及如果我们有时间和资源(仅当我们检查多个密码时才是合理的),请使用Rainbow Tables。

回答

通过一系列检查以确保其符合最低标准:

  • 至少8个字符
  • 包含至少一个非字母数字符号
  • 不匹配或者包含用户名/电子邮件/等。
  • 等等

这是一个报告密码强度的jQuery插件(我自己没有尝试过):
http://phiras.wordpress.com/2007/04/08/password-strength-meter-a-jquery-plugin/

并将同样的东西移植到PHP:
http://www.alixaxel.com/wordpress/2007/06/09/php-password-strength-algorithm/

回答

根据语言,我通常使用正则表达式检查它是否具有:

  • 至少一个大写字母和一个小写字母
  • 至少一个数字
  • 至少一个特殊字符
  • 至少六个字符的长度

我们可以要求以上所有条件,或者使用强度计类型的脚本。对于我的力量计,如果密码的长度正确,则密码的评估如下:

  • 满足一个条件:弱密码
  • 满足两个条件:中等密码
  • 满足所有条件:强密码

我们可以调整以上以满足需求。

回答

要检查的两个最简单的指标是:

  • 长度。我至少要说8个字符。
  • 密码包含的不同字符类的数量。这些通常是小写字母,大写字母,数字和标点符号以及其他符号。强度高的密码将至少包含这些类别中的三个类别的字符;如果我们强制使用数字或者其他非字母字符,则会大大降低字典攻击的效率。

回答

维基百科页面(http://en.wikipedia.org/wiki/Random_password_generator#Stronger_methods)概述了一种通用算法。我还在http://webtecker.com/2008/03/26/collection-of-password-strength-scripts/找到了一些脚本。其中一些是在MIT许可证下的,因此我们可以查看代码,弄清楚它们如何计算强度。我发现维基百科条目也很有帮助。

回答

除了上周混合使用字母,数字和符号的标准方法外,我在上周向MyOpenId注册时还注意到,密码检查器会告诉我们密码是否基于词典单词,即使我们添加数字或者用相似数字替换字母(使用零而不是'o',使用'1'代替'i',等等)。

我印象深刻。

回答

面向对象的方法将是一组规则。为每个规则分配权重并对其进行迭代。在伪代码中:

abstract class Rule {

    float weight;

    float calculateScore( string password );

}

计算总分:

float getPasswordStrength( string password ) {     

    float totalWeight = 0.0f;
    float totalScore  = 0.0f;

    foreach ( rule in rules ) {

       totalWeight += weight;
       totalScore  += rule.calculateScore( password ) * rule.weight;

    }

    return (totalScore / totalWeight) / rules.count;

}

基于存在的字符类数量的示例规则算法:

float calculateScore( string password ) {

    float score = 0.0f;

    // NUMBER_CLASS is a constant char array { '0', '1', '2', ... }
    if ( password.contains( NUMBER_CLASS ) )
        score += 1.0f;

    if ( password.contains( UPPERCASE_CLASS ) )
        score += 1.0f;

    if ( password.contains( LOWERCASE_CLASS ) )
        score += 1.0f;

    // Sub rule as private method
    if ( containsPunctuation( password ) )
        score += 1.0f;

    return score / 4.0f;

}

回答

我写了一个小的Javascript应用程序。看看:另一个密码表。我们可以下载源代码并在GPL下使用/修改它。玩得开心!

回答

我不知道是否有人会觉得这有用,但是我真的很喜欢phear建议的规则集的想法,所以我去写了一个规则Python 2.6类(尽管它可能与2.5兼容):

import re

class SecurityException(Exception):
    pass

class Rule:
    """Creates a rule to evaluate against a string.
    Rules can be regex patterns or a boolean returning function.
    Whether a rule is inclusive or exclusive is decided by the sign
    of the weight. Positive weights are inclusive, negative weights are
    exclusive. 

    Call score() to return either 0 or the weight if the rule 
    is fufilled. 

    Raises a SecurityException if a required rule is violated.
    """

    def __init__(self,rule,weight=1,required=False,name=u"The Unnamed Rule"):
        try:
            getattr(rule,"__call__")
        except AttributeError:
            self.rule = re.compile(rule) # If a regex, compile
        else:
            self.rule = rule  # Otherwise it's a function and it should be scored using it

        if weight == 0:
            return ValueError(u"Weights can not be 0")

        self.weight = weight
        self.required = required
        self.name = name

    def exclusive(self):
        return self.weight < 0
    def inclusive(self):
        return self.weight >= 0
    exclusive = property(exclusive)
    inclusive = property(inclusive)

    def _score_regex(self,password):
        match = self.rule.search(password)
        if match is None:
            if self.exclusive: # didn't match an exclusive rule
                return self.weight
            elif self.inclusive and self.required: # didn't match on a required inclusive rule
                raise SecurityException(u"Violation of Rule: %s by input \"%s\"" % (self.name.title(), password))
            elif self.inclusive and not self.required:
                return 0
        else:
            if self.inclusive:
                return self.weight
            elif self.exclusive and self.required:
                raise SecurityException(u"Violation of Rule: %s by input \"%s\"" % (self.name,password))
            elif self.exclusive and not self.required:
                return 0

        return 0

    def score(self,password):
        try:
            getattr(self.rule,"__call__")
        except AttributeError:
            return self._score_regex(password)
        else:
            return self.rule(password) * self.weight

    def __unicode__(self):
        return u"%s (%i)" % (self.name.title(), self.weight)

    def __str__(self):
        return self.__unicode__()

我希望有人觉得这有用!

用法示例:

rules = [ Rule("^foobar",weight=20,required=True,name=u"The Fubared Rule"), ]
try:
    score = 0
    for rule in rules:
        score += rule.score()
except SecurityException e:
    print e 
else:
    print score

免责声明:未经单元测试

回答

Cracklib很棒,并且在较新的软件包中提供了一个Python模块。但是,在尚不具备此功能的系统(例如CentOS 5)上,我为系统cryptlib编写了一个ctypes包装器。这在无法安装python-libcrypt的系统上也可以使用。它确实需要具有ctypes的python,因此对于CentOS 5,我们必须安装并使用python26软件包。

它还具有以下优点:可以使用用户名并检查包含该用户名的密码或者基本类似的密码,例如libcrypt的" FascistGecos"功能,但不需要用户存在于/ etc / passwd中。

我的ctypescracklib库可在github上找到

一些示例使用:

>>> FascistCheck('jafo1234', 'jafo')
'it is based on your username'
>>> FascistCheck('myofaj123', 'jafo')
'it is based on your username'
>>> FascistCheck('jxayfoxo', 'jafo')
'it is too similar to your username'
>>> FascistCheck('cretse')
'it is based on a dictionary word'

回答

阅读其他有用的答案后,这就是我要去的地方:

-1与用户名相同
+0包含用户名
+1个超过7个字符
+1个以上的11个字符
+1包含数字
+1混合大小写
+1包含标点符号
+1个不可打印的字符

pwscore.py:

import re
import string
max_score = 6
def score(username,passwd):
    if passwd == username:
        return -1
    if username in passwd:
        return 0
    score = 0
    if len(passwd) > 7:
        score+=1
    if len(passwd) > 11:
        score+=1
    if re.search('\d+',passwd):
        score+=1
    if re.search('[a-z]',passwd) and re.search('[A-Z]',passwd):
        score+=1
    if len([x for x in passwd if x in string.punctuation]) > 0:
        score+=1
    if len([x for x in passwd if x not in string.printable]) > 0:
        score+=1
    return score

用法示例:

import pwscore
    score = pwscore(username,passwd)
    if score < 3:
        return "weak password (score=" 
             + str(score) + "/"
             + str(pwscore.max_score)
             + "), try again."

可能不是最有效的,但似乎很合理。
不确定FascistCheck =>'太类似于用户名'是
值得。

'abc123ABC!@'=如果不是用户名的超集,则得分为6/6

也许那应该得分更低。