如何检查密码强度? [关闭]
Posted
技术标签:
【中文标题】如何检查密码强度? [关闭]【英文标题】:How to check password strength? [closed] 【发布时间】:2011-09-03 08:10:45 【问题描述】:如何使用 .Net Framework 检查密码强度(string
)?
【问题讨论】:
您发现的结果是否一致且可比较? 你的实力标准是什么?您能更明确地说明您要测试的内容吗? 我的标准是熵——没有一个答案能满足这个要求。根据this question on crypto香农是理论上的解决方案。在实践中,您还必须从字典/***/技术语言中删除所有内容。 【参考方案1】:基本但合乎逻辑的:
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
【讨论】:
password123
是中等密码吗?当您从 0 而不是 1 开始得分时会更好一些。最好使用 github.com/dropbox/zxcvbn 之类的东西【参考方案2】:
“密码强度”是一个相当笼统的术语,它可能意味着密码字符数、使用的字符范围(基数)、破解(暴力破解)密码所需的时间等。
衡量密码加密强度的最佳方法之一是计算密码有多少位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;
【讨论】:
【参考方案3】:如果我可以展示我对示例的自定义实现,例如 Teoman Soygul(以及我见过的与他类似的其他示例)......我的实现有不同的评分方案,并使用最低要求以及检查重复字符。
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, @"[~`!@#$%\^\&\*\(\)\-_\+=\[\\]\\|\\;:'\""<\,>\.\?\/£]", 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 ContainsNumberCharsget 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()
中定义自己的规则
【讨论】:
这远远优于许多其他答案,或者至少是从这种实现中派生的一些东西。期望的事情是获得一个对象,该对象记录有关密码的有用信息,人们可以从中做出明智的决定。虽然在这种情况下它并不是那么重要(甚至不是瓶颈),但这种方式的性能也大大提高。我看到上面的正则表达式实现通过重新运行正则表达式反复测试是否存在某种大小写的字母!更好的是一次获取信息:是否有大写等。其他检查仍然可以添加: 例如:passwd.match(/(\d.*\d)/)
- 我认为来自上述答案之一的检查是在询问:是否出现过一个或多个数字,然后是另一个数字(但是,这个正则表达式实际上可能与连续两位数,您可以在中间用 ! 重写)。在这种 c# 案例中,可以在没有正则表达式的情况下解决这个问题,记录:大写是否不止一次被非大写打破,小写和数字也是如此。无论如何,这是更好的方法,然后您就有记录可以做出决定。【参考方案5】:
这是我使用的一个简单的 javascript 示例,将其移植到 .Net 应该不会很难,
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;
【讨论】:
【参考方案6】:这是我自己的代码,用于基于信息熵和 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, @"[~`!@#$%\^\&\*\(\)\-_\+=\[\\]\\|\\;:'\""<\,>\.\?\/£]", 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;
【讨论】:
【参考方案7】:应根据几个参数检查密码的强度,例如是否存在特殊字符和数字、密码的长度等。
我发现下面的教程有很好的演示:
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+'%');
);
);
【讨论】:
以上是关于如何检查密码强度? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章