it-swarm-vi.tech

Cách tốt nhất để kiểm tra độ mạnh của mật khẩu là gì?

Cách tốt nhất để đảm bảo rằng người dùng cung cấp mật khẩu là mật khẩu mạnh trong đăng ký hoặc thay đổi hình thức mật khẩu là gì?

Một ý tưởng tôi đã có (trong 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
42
Ed L

Tùy thuộc vào ngôn ngữ, tôi thường sử dụng các biểu thức thông thường để kiểm tra xem nó có:

  • Ít nhất một chữ hoa và một chữ cái [.__.]
  • Ít nhất một số
  • Ít nhất một nhân vật đặc biệt
  • Độ dài ít nhất sáu ký tự

Bạn có thể yêu cầu tất cả những điều trên, hoặc sử dụng loại kịch bản đo cường độ. Đối với máy đo sức mạnh của tôi, nếu mật khẩu có độ dài phù hợp, nó được đánh giá như sau:

  • Một điều kiện đáp ứng: mật khẩu yếu
  • Hai điều kiện đáp ứng: mật khẩu trung bình
  • Tất cả các điều kiện đáp ứng: mật khẩu mạnh

Bạn có thể điều chỉnh ở trên để đáp ứng nhu cầu của bạn.

18
VirtuosiMedia

Cách tiếp cận hướng đối tượng sẽ là một bộ quy tắc. Chỉ định trọng số cho mỗi quy tắc và lặp qua chúng. Trong mã psuedo:

abstract class Rule {

    float weight;

    float calculateScore( string password );

}

Tính tổng số điểm:

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;

}

Một thuật toán quy tắc ví dụ, dựa trên số lượng các lớp ký tự hiện tại:

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;

}
9
user9116

Hai số liệu đơn giản nhất để kiểm tra là:

  1. Chiều dài. Tôi muốn nói tối thiểu 8 ký tự.
  2. Số lượng các lớp ký tự khác nhau mà mật khẩu chứa. Đây thường là, chữ thường, chữ in hoa, số và dấu chấm câu và các ký hiệu khác. Một mật khẩu mạnh sẽ chứa các ký tự từ ít nhất ba trong số các lớp này; nếu bạn buộc một số hoặc ký tự không phải là chữ cái khác, bạn sẽ giảm đáng kể hiệu quả của các cuộc tấn công từ điển.
3
Dave Webb

Cracklib là tuyệt vời, và trong các gói mới hơn có một mô-đun Python có sẵn cho nó. Tuy nhiên, trên các hệ thống chưa có nó, chẳng hạn như CentOS 5, tôi đã viết một trình bao bọc ctypes cho hệ thống mã hóa. Điều này cũng sẽ hoạt động trên một hệ thống mà bạn không thể cài đặt python-libcrypt. Nó does yêu cầu python có sẵn ctypes, vì vậy đối với CentOS 5, bạn phải cài đặt và sử dụng gói python26.

Nó cũng có lợi thế là nó có thể lấy tên người dùng và kiểm tra mật khẩu có chứa nó hoặc tương tự về cơ bản, như hàm libcrypt "FascistGecos" nhưng không yêu cầu người dùng tồn tại trong/etc/passwd.

Thư viện của tôi ctypescracklib có sẵn trên github

Một số ví dụ sử dụng:

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

sau khi đọc các câu trả lời hữu ích khác, đây là những gì tôi sẽ làm với:

-1 giống như tên người dùng
[.__.] + 0 chứa tên người dùng
[.__.] + 1 hơn 7 ký tự
[.__.] + 1 hơn 11 ký tự
[.__.] + 1 chứa các chữ số
[.__.] + 1 kết hợp chữ thường và chữ hoa
[.__.] + 1 chứa dấu câu
[.__.] + 1 char không in được 

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

sử dụng ví dụ:

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

có lẽ không phải là hiệu quả nhất, nhưng có vẻ hợp lý. [.__.] không chắc chắn FascistCheck => 'quá giống với tên người dùng' là [.__.] đáng giá.

'abc123ABC! @ £' = điểm 6/6 nếu không phải là siêu tên người dùng

có lẽ nên ghi điểm thấp hơn.

2
siznax

Có mở và miễn phí John the Ripper cracker mật khẩu, một cách tuyệt vời để kiểm tra cơ sở dữ liệu mật khẩu hiện có.

1
tante

Vâng, đây là những gì tôi sử dụng:

   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

Tôi đã viết một ứng dụng Javascript nhỏ. Hãy xem: Tuy nhiên, một mật khẩu khác . Bạn có thể tải xuống nguồn và sử dụng/sửa đổi nó theo GPL. Chúc vui vẻ!

0
ReneS

Tôi không biết liệu có ai thấy điều này hữu ích không, nhưng tôi thực sự thích ý tưởng về một quy tắc như được đề xuất bởi phear nên tôi đã đi và viết một quy tắc Python 2.6 (mặc dù nó có thể tương thích với 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__()

Tôi hi vọng ai đó thấy nó hữu ích!

Cách sử dụng ví dụ:

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

TUYÊN BỐ TỪ CHỐI: Không thử nghiệm đơn vị

0
SapphireSun

Ngoài cách tiếp cận tiêu chuẩn pha trộn alpha, số và ký hiệu, tôi nhận thấy khi tôi đăng ký với MyOpenId tuần trước, trình kiểm tra mật khẩu sẽ cho bạn biết nếu mật khẩu của bạn dựa trên từ điển Word, ngay cả khi bạn thêm số hoặc thay thế chữ cái bằng số tương tự (sử dụng số 0 thay vì 'o', '1' thay vì 'i', v.v.).

Tôi đã rất ấn tượng.

0
Steve Morgan