it-swarm-id.com

Apa cara terbaik untuk memeriksa kekuatan kata sandi?

Apa cara terbaik untuk memastikan bahwa kata sandi yang diberikan pengguna adalah kata sandi yang kuat dalam formulir pendaftaran atau ubah kata sandi?

Satu ide yang saya miliki (dengan 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

Bergantung pada bahasanya, saya biasanya menggunakan ekspresi reguler untuk memeriksa apakah ada:

  • Setidaknya satu huruf besar dan satu Huruf kecil
  • Setidaknya satu nomor
  • Setidaknya satu karakter khusus
  • Panjang setidaknya enam karakter

Anda dapat meminta semua hal di atas, atau menggunakan jenis skrip pengukur kekuatan. Untuk meter kekuatan saya, jika kata sandi memiliki panjang yang tepat, itu dievaluasi sebagai berikut:

  • Satu syarat bertemu: kata sandi lemah
  • Dua kondisi terpenuhi: kata sandi sedang
  • Semua kondisi terpenuhi: kata sandi yang kuat

Anda dapat menyesuaikan hal di atas untuk memenuhi kebutuhan Anda.

18
VirtuosiMedia

Pendekatan berorientasi objek akan menjadi seperangkat aturan. Tetapkan bobot untuk setiap aturan dan beralihlah ke aturan itu. Dalam kode psuedo:

abstract class Rule {

    float weight;

    float calculateScore( string password );

}

Menghitung skor total:

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;

}

Contoh algoritma aturan, berdasarkan jumlah kelas karakter yang ada:

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

Dua metrik paling sederhana untuk diperiksa adalah:

  1. Panjangnya. Saya akan mengatakan 8 karakter sebagai minimum.
  2. Jumlah kelas karakter berbeda yang berisi kata sandi. Ini biasanya, huruf kecil, huruf besar, angka dan tanda baca dan simbol lainnya. Kata sandi yang kuat akan berisi karakter dari setidaknya tiga kelas ini; jika Anda memaksa angka atau karakter non-alfabet lainnya, Anda secara signifikan mengurangi efektivitas serangan kamus.
3
Dave Webb

Cracklib bagus, dan dalam paket yang lebih baru ada modul Python yang tersedia untuk itu. Namun, pada sistem yang belum memilikinya, seperti CentOS 5, saya telah menulis pembungkus ctypes untuk sistem cryptlib. Ini juga akan bekerja pada sistem yang Anda tidak dapat menginstal python-libcrypt. Itu tidak memerlukan python dengan ctypes tersedia, jadi untuk CentOS 5 Anda harus menginstal dan menggunakan paket python26.

Ini juga memiliki keuntungan bahwa ia dapat mengambil nama pengguna dan memeriksa kata sandi yang mengandungnya atau secara substansial mirip, seperti fungsi libcrypt "FascistGecos" tetapi tanpa mengharuskan pengguna untuk ada di/etc/passwd.

Pustaka ctypescracklib saya tersedia di github

Beberapa contoh menggunakan:

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

setelah membaca jawaban bermanfaat lainnya, inilah yang akan saya lakukan:

-1 sama dengan nama pengguna
+ 0 berisi nama pengguna
+ 1 lebih dari 7 karakter
+ 1 lebih dari 11 karakter
+1 berisi digit
+ 1 campuran huruf kecil dan besar
+1 berisi tanda baca
+ 1 char tidak dapat dicetak 

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

contoh penggunaan:

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

mungkin bukan yang paling efisien, tetapi tampaknya masuk akal. tidak yakin FascistCheck => 'terlalu mirip dengan nama pengguna' adalah sepadan.

'abc123ABC! @ £' = skor 6/6 jika bukan superset nama pengguna

mungkin itu seharusnya skor lebih rendah.

2
siznax

Ada cracker terbuka dan bebas John the Ripper yang merupakan cara terbaik untuk memeriksa basis data kata sandi yang ada.

1
tante

Nah inilah yang saya gunakan:

   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

Saya menulis aplikasi Javascript kecil. Lihatlah: Yet Another Password Meter . Anda dapat mengunduh sumber dan menggunakan/memodifikasinya di bawah GPL. Selamat bersenang-senang!

0
ReneS

Saya tidak tahu apakah ada yang akan menemukan ini berguna, tapi saya benar-benar menyukai gagasan aturan seperti yang disarankan oleh phear jadi saya pergi dan menulis sebuah aturan kelas Python 2.6 (walaupun mungkin kompatibel dengan 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__()

Saya harap seseorang menemukan ini berguna!

Contoh penggunaan:

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

PENOLAKAN: Tidak diuji unit

0
SapphireSun

Selain pendekatan standar pencampuran alfa, angka dan simbol, saya perhatikan ketika saya mendaftar dengan MyOpenId minggu lalu, pemeriksa kata sandi memberi tahu Anda apakah kata sandi Anda didasarkan pada kamus kata, bahkan jika Anda menambahkan angka atau mengganti alfa dengan angka yang sama (menggunakan nol sebagai ganti 'o', '1' alih-alih 'i', dll.).

Saya cukup terkesan.

0
Steve Morgan