2011-05-27 88 views
12

如何檢查使用.NET Framework密碼(作爲string)的實力?如何檢查密碼強度?

+0

你已經找到了那些生產一致性和可比較的結果? – 2011-05-27 12:36:17

+0

你的實力標準是什麼?你能更清楚地知道你想要測試什麼嗎? – 2014-09-29 12:49:01

+0

我的標準是熵 - 沒有答案滿足那個。根據[加密上的這個問題](https://crypto.stackexchange.com/questions/374/how-should-i-calculate-the-entropy-of-a-password)香農是理論上的解決方案。在實踐中,你還必須從字典/維基百科/技術語言中消除所有內容。 – mbx 2017-06-09 09:40:08

回答

7

基本的,但邏輯之一:

enum PasswordScore 
{ 
    Blank = 0, 
    VeryWeak = 1, 
    Weak = 2, 
    Medium = 3, 
    Strong = 4, 
    VeryStrong = 5 
} 

public class PasswordAdvisor 
{ 
    public static PasswordScore CheckStrength(string password) 
    { 
     int score = 1; 

     if (password.Length < 1) 
      return PasswordScore.Blank; 
     if (password.Length < 4) 
      return PasswordScore.VeryWeak; 

     if (password.Length >= 8) 
      score++; 
     if (password.Length >= 12) 
      score++; 
     if (Regex.Match(password, @"/\d+/", RegexOptions.ECMAScript)) 
      score++; 
     if (Regex.Match(password, @"/[a-z]/", RegexOptions.ECMAScript) && 
      Regex.Match(password, @"/[A-Z]/", RegexOptions.ECMAScript)) 
      score++; 
     if (Regex.Match(password, @"/.[!,@,#,$,%,^,&,*,?,_,~,-,£,(,)]/", RegexOptions.ECMAScript)) 
      score++; 

     return (PasswordScore)score; 
    } 
} 

編號:http://passwordadvisor.com/CodeAspNet.aspx

+0

'password123'是一箇中等密碼?當你在0而不是1,更好地利用類似https://github.com/dropbox/zxcvbn – Tieme 2016-02-13 00:12:32

1

這是我用的,將它移植到.NET應該不會很辛苦一個簡單的JavaScript例如,

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; 
} 
3

如果我可以展示我的定製化實施的例子,如泰奧曼Soygul的(和其他人我見過像他)......我的實現有不同的計分方案,並使用分imum要求以及重複字符的檢查。

public enum PasswordScore 
{ 
    Blank = 0, 
    TooShort = 1, 
    RequirementsNotMet = 2, 
    VeryWeak = 3, 
    Weak = 4, 
    Fair = 5, 
    Medium = 6, 
    Strong = 7, 
    VeryStrong = 8 
} 

public static PasswordScore CheckStrength(string password) 
    { 
     int score = 0; 

     // using three requirements here: min length and two types of characters (numbers and letters) 
     bool blnMinLengthRequirementMet = false; 
     bool blnRequirement1Met = false; 
     bool blnRequirement2Met = false; 

     // check for chars in password 
     if (password.Length < 1) 
      return PasswordScore.Blank; 

     // if less than 6 chars, return as too short, else, plus one 
     if (password.Length < 6) 
     { 
      return PasswordScore.TooShort; 
     } 
     else 
     { 
      score++; 
      blnMinLengthRequirementMet = true; 
     } 

     // if 8 or more chars, plus one 
     if (password.Length >= 8) 
      score++; 

     // if 10 or more chars, plus one 
     if (password.Length >= 10) 
      score++; 

     // if password has a number, plus one 
     if (Regex.IsMatch(password, @"[\d]", RegexOptions.ECMAScript)) 
     { 
      score++; 
      blnRequirement1Met = true; 
     } 

     // if password has lower case letter, plus one 
     if (Regex.IsMatch(password, @"[a-z]", RegexOptions.ECMAScript)) 
     { 
      score++; 
      blnRequirement2Met = true; 
     } 

     // if password has upper case letter, plus one 
     if (Regex.IsMatch(password, @"[A-Z]", RegexOptions.ECMAScript)) 
     { 
      score++; 
      blnRequirement2Met = true; 
     } 

     // if password has a special character, plus one 
     if (Regex.IsMatch(password, @"[~`[email protected]#$%\^\&\*\(\)\-_\+=\[\{\]\}\|\\;:'\""<\,>\.\?\/£]", RegexOptions.ECMAScript)) 
      score++; 

     // if password is longer than 2 characters and has 3 repeating characters, minus one (to minimum of score of 3) 
     List<char> lstPass = password.ToList(); 
     if (lstPass.Count >= 3) 
     { 
      for (int i = 2; i < lstPass.Count; i++) 
      { 
       char charCurrent = lstPass[i]; 
       if (charCurrent == lstPass[i - 1] && charCurrent == lstPass[i - 2] && score >= 4) 
       { 
        score++; 
       } 
      } 
     } 

     if (!blnMinLengthRequirementMet || !blnRequirement1Met || !blnRequirement2Met) 
     { 
      return PasswordScore.RequirementsNotMet; 
     } 

     return (PasswordScore)score; 
    } 
4

這裏有一個簡單的我已經寫了:

/// <summary> 
/// Evaluates a password 
/// </summary> 
public class PasswordEvaluator 
{ 
    public string Password { get; private set; } 
    public int Length { get; private set; } 
    public int TotalNumberChars { get; private set; } 
    public bool ContainsNumberChars{get { return TotalNumberChars > 0; }} 
    public int TotalUppercaseChars { get; private set; } 
    public bool ContainsUppercaseChars { get { return TotalUppercaseChars > 0; } } 
    public int TotalLowercaseChars { get; private set; } 
    public bool ContainsLowercaseChars { get { return TotalLowercaseChars > 0; } } 
    public int TotalSpecialChars { get; private set; } 
    public bool ContainsSpecialChars { get { return TotalSpecialChars > 0; } } 

    public PasswordEvaluator(string password) 
    { 
     Password = password.Trim(); 
     Length = Password.Length; 
     foreach (var c in Password) 
     { 
      var charCode = (int)c; 
      if (charCode >= 48 && charCode <= 57) TotalNumberChars++; 
      else if (charCode >= 65 && charCode <= 90) TotalUppercaseChars++; 
      else if (charCode >= 97 && charCode <= 122) TotalLowercaseChars++; 
      else TotalSpecialChars++; 
     } 
    } 
    public bool StrongEnough() 
    { 
     // Minimum length requirement 
     if (Length < Settings.PasswordMinLength) return false; 

     // Mixed case requirement 
     if (!ContainsLowercaseChars && !ContainsUppercaseChars) return false; 

     // Special chars requirement 
     if (TotalSpecialChars < 3) return false; 

     // Min lower case chars requirement 
     if (TotalLowercaseChars < 3) return false; 

     // Min upper case chars requirement 
     if (TotalUppercaseChars < 3) return false; 

     return true; 
    } 
} 

可以在StrongEnough()

+0

這是遠遠優於許多其他的答案,或者至少從東西這種實現衍生開始得分好一點。期望的是獲得一個對象,記錄有關密碼的有用信息,從中可以做出明智的決定。雖然在這種情況下這並不重要(甚至不是瓶頸),但這種方式的性能也大大提高。我看到上面的正則表達式實現,通過重新運行正則表達式來重複測試某個特定情況的字母是否存在!更好的辦法是獲取一次信息:是否有大寫字母等等。還可以添加其他檢查: – 2017-10-18 22:59:06

+0

如:'passwd.match(/(\ d。* \ d)/)' - 我認爲這是從上面的答案之一是問:一個數字或更多是否出現,然後是另一個數字(然而,這個正則表達式實際上可能會匹配兩行數字,您可以使用!重寫!)。在這個C#的情況下,人們可以不用正則表達式來計算出這種情況,記錄:大小寫不止一次出現不是大寫,而是小寫和數字相同。無論如何,這是最好的方法,你有一個記錄來作出決定。 – 2017-10-18 23:02:50

0

定義自己的規則,這是基於信息熵對密碼強度檢查用我自己的代碼和NIST指南。但是這種方法並沒有考慮到「人」語言因素。密碼的

public enum PasswordScore 
{ 
    Blank, 
    VeryWeak, 
    Weak, 
    Medium, 
    Strong, 
    VeryStrong 
} 

public static PasswordScore CheckPasswordStrength(string password) 
{ 
    int N = 0; 
    int L = password.Length; 
    if (L == 0) 
     return PasswordScore.Blank; 
    if (Regex.IsMatch(password, @"[\d]", RegexOptions.ECMAScript)) 
     N += 10; 
    if (Regex.IsMatch(password, @"[a-z]", RegexOptions.ECMAScript)) 
     N += 26; 
    if (Regex.IsMatch(password, @"[A-Z]", RegexOptions.ECMAScript)) 
     N += 26; 
    if (Regex.IsMatch(password, @"[~`[email protected]#$%\^\&\*\(\)\-_\+=\[\{\]\}\|\\;:'\""<\,>\.\?\/£]", RegexOptions.ECMAScript) && password.Length > 8) 
     N += 33; 
    int H = Convert.ToInt32(L * (Math.Round(Math.Log(N)/Math.Log(2)))); 
    if (H <= 32) return PasswordScore.VeryWeak; 
    if (H <= 48) return PasswordScore.Weak; 
    if (H <= 64) return PasswordScore.Medium; 
    if (H <= 80) return PasswordScore.Strong; 
    return PasswordScore.VeryStrong; 
} 
0

強度應該代表的幾個參數,如特殊字符和數字,密碼長度存在檢查等

我發現下面的教程,很好的演示:

http://tinytute.com/2014/06/03/animated-password-strength-checker-quick-easy/

jQuery的代碼塊:

$(document).ready(function(){ 

    $("#textBox").keyup(function(){ 

     var passWord = $("#textBox").val(); 
     var passLength = passWord.length; 
     var specialFlag = 0; 
     var numberFlag = 0; 
     var numberGenerator = 0; 
     var total = 0; 

     if(/^[a-zA-Z0-9- ]*$/.test(passWord) == false) { 

      specialFlag =20; 
     } 


     if(passWord.match(/[0-9]/)) { 

      numberFlag = 25; 
     } 

     if(passLength>4&&passLength<=6){ 
      numberGenerator =25; 
     }else if(passLength>=7&&passLength<=9){ 
      numberGenerator =35; 
     }else if(passLength>9){ 
      numberGenerator =55; 
     }else if(passLength>0&&passLength<=4){ 
      numberGenerator =15; 
     }else{ 
      numberGenerator =0; 
     } 

     total = numberGenerator + specialFlag + numberFlag; 
     if(total<30){ 
      $('#progressBar').css('background-color','#CCC'); 
     }else if(total<60&&total>=30){ 

      $('#progressBar').css('background-color','#FF6600'); 

     }else if(total>=60&&total<90){ 

      $('#progressBar').css('background-color','#FFCC00'); 

     }else if(total>=90){ 

      $('#progressBar').css('background-color','#0f0'); 

     } 
     $('#progressBar').css('width',total+'%'); 

    }); 

}); 
5

「密碼強度」是一個相當通用的術語,它可能意味着密碼字符數,使用的字符範圍(基數),破解密碼所需的時間(暴力破解)等。

其中一種最好的方法衡量一個密碼的加密強度是計算密碼多少entropy位有(雖然這通常是衡量隨機密碼更準確。你會得到否則的估計熵結果),

// Only accurate for passwords in ASCII. 
public double CalculateEntropy(string password) 
{ 
    var cardinality = 0; 

    // Password contains lowercase letters. 
    if (password.Any(c => char.IsLower(c))) 
    { 
     cardinality = 26; 
    } 

    // Password contains uppercase letters. 
    if (password.Any(c => char.IsUpper(c))) 
    { 
     cardinality += 26; 
    } 

    // Password contains numbers. 
    if (password.Any(c => char.IsDigit(c))) 
    { 
     cardinality += 10; 
    } 

    // Password contains symbols. 
    if (password.IndexOfAny("\\|¬¦`!\"£$%^&*()_+-=[]{};:'@#~<>,./? ".ToCharArray()) >= 0) 
    { 
     cardinality += 36; 
    } 

    return Math.Log(cardinality, 2) * password.Length; 
}