it-swarm-ko.tech

비밀번호의 안전성을 확인하는 가장 좋은 방법은 무엇입니까?

사용자 제공 암호가 등록 또는 암호 변경 양식에서 강력한 암호인지 확인하는 가장 좋은 방법은 무엇입니까?

내가 가진 하나의 아이디어 (파이썬)

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
43
Ed L

1 : 자주 사용하는 암호 제거
자주 사용하는 비밀번호 목록과 비교하여 입력 한 비밀번호를 확인합니다 (예 : 유출 된 LinkedIn 비밀번호 목록에서 상위 100.000 개 비밀번호 참조 : http://www.adeptus-mechanicus.com/codex/linkhap/) combo_not.Zip ), leetspeek 대체 : A @, E3, B8, S5 등을 포함해야합니다.
아래 파트 2로 이동하기 전에 입력 된 구문에서이 목록에 대해 적중 된 비밀번호의 일부를 제거하십시오.

2 : 사용자에게 어떤 규칙도 강제하지 마십시오

암호의 황금률은 길수록 좋습니다.
대부분의 사용자가 다음을 수행하기 때문에 대문자, 숫자 및 기호를 강제로 사용하지 마십시오.-첫 글자를 대문자로 만듭니다. -끝에 숫자 1를 입력하세요. -기호가 필요한 경우 그 뒤에 !를 입력합니다.

대신 비밀번호 안전성 확인

적절한 시작점은 다음을 참조하십시오 : http://www.passwordmeter.com/

최소한 다음 규칙을 제안합니다.

Additions (better passwords)
-----------------------------
- Number of Characters              Flat       +(n*4)   
- Uppercase Letters                 Cond/Incr  +((len-n)*2)     
- Lowercase Letters                 Cond/Incr  +((len-n)*2)     
- Numbers                           Cond       +(n*4)   
- Symbols                           Flat       +(n*6)
- Middle Numbers or Symbols         Flat       +(n*2)   
- Shannon Entropy                   Complex    *EntropyScore

Deductions (worse passwords)
----------------------------- 
- Letters Only                      Flat       -n   
- Numbers Only                      Flat       -(n*16)  
- Repeat Chars (Case Insensitive)   Complex    -    
- Consecutive Uppercase Letters     Flat       -(n*2)   
- Consecutive Lowercase Letters     Flat       -(n*2)   
- Consecutive Numbers               Flat       -(n*2)   
- Sequential Letters (3+)           Flat       -(n*3)   
- Sequential Numbers (3+)           Flat       -(n*3)   
- Sequential Symbols (3+)           Flat       -(n*3)
- Repeated words                    Complex    -       
- Only 1st char is uppercase        Flat       -n
- Last (non symbol) char is number  Flat       -n
- Only last char is symbol          Flat       -n

passwordmeter 를 따르는 것만으로는 충분하지 않습니다. Password1! 매우 약하지만 매우 약합니다. 점수를 매길 때 첫 번째 대문자와 후행 숫자 및 기호를 무시하십시오 (마지막 3 개 규칙에 따라).

섀넌 엔트로피 계산
참조 : 파이썬에서 엔트로피를 계산하는 가장 빠른 방법

3 : 너무 약한 암호를 허용하지 마십시오
사용자가 자멸적인 규칙을 따르도록 강요하지 말고 충분한 점수를 줄 수있는 모든 것을 허용하십시오. 얼마나 높은지는 사용 사례에 따라 다릅니다.

그리고 가장 중요한 것은
암호를 수락하고 데이터베이스에 저장하면 솔트하고 해시해야합니다! .

언어에 따라 일반적으로 정규식을 사용하여 다음이 있는지 확인합니다.

  • 하나 이상의 대문자와 하나의 소문자
  • 하나 이상의 숫자
  • 하나 이상의 특수 문자
  • 6 자 이상의 길이

위의 모든 것을 요구하거나 강도 측정기 유형의 스크립트를 사용할 수 있습니다. 내 강도 측정기의 경우 암호 길이가 올바른 경우 다음과 같이 평가됩니다.

  • 하나의 조건 충족 : 취약한 암호
  • 두 가지 조건 충족 : 중간 암호
  • 모든 조건 충족 : 강력한 암호

필요에 따라 위의 내용을 조정할 수 있습니다.

17
VirtuosiMedia

객체 지향 접근 방식은 일련의 규칙입니다. 각 규칙에 가중치를 할당하고이를 반복합니다. 의사 코드에서 :

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;

}
10
user9116

확인해야 할 가장 간단한 두 가지 측정 항목은 다음과 같습니다.

  1. 길이. 최소한 8 자라고 말하고 싶습니다.
  2. 암호에 포함 된 다른 문자 클래스의 수입니다. 일반적으로 소문자, 대문자, 숫자, 구두점 및 기타 기호입니다. 강력한 암호에는 이러한 클래스 중 3 개 이상의 문자가 포함됩니다. 숫자 또는 기타 비 알파벳 문자를 강제하면 사전 공격의 효과가 크게 감소합니다.
3
Dave Webb

Cracklib는 훌륭하며 최신 패키지에는 사용할 수있는 Python 모듈이 있습니다. 그러나 CentOS 5와 같이 아직 모듈이없는 시스템에서는 ctypes 래퍼를 작성했습니다. 시스템 cryptlib의 경우. 이것은 python-libcrypt를 설치할 수없는 시스템에서도 작동합니다. does require python ctypes를 사용할 수 있으므로 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'
2
Sean Reifschneider

다른 유용한 답변을 읽은 후 다음과 같이하겠습니다.

-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 점

점수가 더 낮을 것입니다.

2
siznax

개방적이고 무료 인 John the Ripper 기존 암호 데이터베이스를 확인하는 좋은 방법 인 암호 크래커가 있습니다.

1
tante

글쎄, 이것이 내가 사용하는 것입니다.

   var getStrength = function (passwd) {
    intScore = 0;
    intScore = (intScore + passwd.length);
    if (passwd.match(/[a-z]/)) {
        intScore = (intScore + 1);
    }
    if (passwd.match(/[A-Z]/)) {
        intScore = (intScore + 5);
    }
    if (passwd.match(/\d+/)) {
        intScore = (intScore + 5);
    }
    if (passwd.match(/(\d.*\d)/)) {
        intScore = (intScore + 5);
    }
    if (passwd.match(/[!,@#$%^&*?_~]/)) {
        intScore = (intScore + 5);
    }
    if (passwd.match(/([!,@#$%^&*?_~].*[!,@#$%^&*?_~])/)) {
        intScore = (intScore + 5);
    }
    if (passwd.match(/[a-z]/) && passwd.match(/[A-Z]/)) {
        intScore = (intScore + 2);
    }
    if (passwd.match(/\d/) && passwd.match(/\D/)) {
        intScore = (intScore + 2);
    }
    if (passwd.match(/[a-z]/) && passwd.match(/[A-Z]/) && passwd.match(/\d/) && passwd.match(/[!,@#$%^&*?_~]/)) {
        intScore = (intScore + 2);
    }
    return intScore;
} 
1
varun

작은 자바 스크립트 애플리케이션을 작성했습니다. 보세요 : Yet Another Password Meter . 소스를 다운로드하고 GPL에서 사용/수정할 수 있습니다. 즐기세요!

0
ReneS

누구도이 기능이 유용하다고 생각할지 모르겠지만 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

면책 조항 : 단위 테스트되지 않음

0
SapphireSun

알파벳, 숫자 및 기호를 혼합하는 표준 접근 방식 외에도 지난주에 MyOpenId에 등록했을 때 비밀번호 검사기가 숫자를 추가하거나 알파벳을 비슷한 숫자로 바꾸더라도 비밀번호가 사전 Word를 기반으로하는지 알려줍니다. ( 'o'대신 0 사용, 'i'대신 '1'사용).

나는 매우 감동했습니다.

0
Steve Morgan