137 lines
5.3 KiB
C#
137 lines
5.3 KiB
C#
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
|
|
//https://stephenhaunts.com/2014/01/31/checking-the-strength-of-a-password/
|
|
//https://github.com/danielmiessler/SecLists/tree/master/Passwords
|
|
|
|
namespace Knoks.Framework.Security
|
|
{
|
|
public sealed class PasswordStrength : IPasswordStrength
|
|
{
|
|
private readonly static string[] _weakPasswordList = { "welcome", "123456", "password", "12345678", "qwerty", "123456789", "12345", "1234", "111111", "1234567", "dragon", "123123", "baseball", "abc123", "football", "monkey", "letmein", "696969", "shadow", "master", "666666", "qwertyuiop", "123321", "mustang", "1234567890", "michael", "654321", "pussy", "superman", "1qaz2wsx", "7777777", "fuckyou", "121212", "000000", "qazwsx", "123qwe", "killer", "trustno1", "jordan", "jennifer", "zxcvbnm", "asdfgh", "hunter", "buster", "soccer", "harley", "batman", "andrew", "tigger", "sunshine", "iloveyou", "fuckme", "2000", "charlie", "robert", "thomas", "hockey", "ranger", "daniel", "starwars", "klaster", "112233", "george", "asshole", "computer", "michelle", "jessica", "pepper", "1111", "zxcvbn", "555555", "11111111", "131313", "freedom", "777777", "pass", "fuck", "maggie", "159753", "aaaaaa", "ginger", "princess", "joshua", "cheese", "amanda", "summer", "love", "ashley", "6969", "nicole", "chelsea", "biteme", "matthew", "access", "yankees", "987654321", "dallas", "austin", "thunder", "taylor", "matrix" };
|
|
|
|
public async Task<PasswordScore> CheckStrength(string password)
|
|
{
|
|
return await Task.Run(() =>
|
|
{
|
|
int score = 0;
|
|
|
|
if (string.IsNullOrEmpty(password))
|
|
{
|
|
return PasswordScore.Blank;
|
|
}
|
|
|
|
if (IsPasswordInWeakList(password))
|
|
{
|
|
return PasswordScore.Weak;
|
|
}
|
|
|
|
if (password.Length < 1)
|
|
{
|
|
return PasswordScore.Blank;
|
|
}
|
|
|
|
if (password.Length < 4)
|
|
{
|
|
return PasswordScore.VeryWeak;
|
|
}
|
|
|
|
if (password.Length >= 8)
|
|
{
|
|
score++;
|
|
}
|
|
|
|
if (password.Length >= 10)
|
|
{
|
|
score++;
|
|
}
|
|
|
|
if (Regex.Match(password, @"\d", RegexOptions.ECMAScript).Success)
|
|
{
|
|
score++;
|
|
}
|
|
|
|
if (Regex.Match(password, @"[a-z]", RegexOptions.ECMAScript).Success &&
|
|
Regex.Match(password, @"[A-Z]", RegexOptions.ECMAScript).Success)
|
|
{
|
|
score++;
|
|
}
|
|
|
|
if (Regex.Match(password, @"[!,@,#,$,%,^,&,*,?,_,~,-,£,(,)]", RegexOptions.ECMAScript).Success)
|
|
{
|
|
score++;
|
|
}
|
|
|
|
return (PasswordScore)score;
|
|
});
|
|
}
|
|
|
|
private static bool IsPasswordInWeakList(string password)
|
|
{
|
|
foreach (string weakPassword in _weakPasswordList)
|
|
{
|
|
if (string.Compare(password, weakPassword, System.StringComparison.OrdinalIgnoreCase) == 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (PerformSubstitutions(weakPassword, password))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private static bool PerformSubstitutions(string weakPassword, string password)
|
|
{
|
|
char[] vowels = { 'A', 'a', 'e', 'i', 'o', 's', 'S' };
|
|
char[] vowelSubstitution = { '4', '@', '3', '1', '0', '$', '5' };
|
|
|
|
ReplaceLettersWithSubStitutions(password, vowels, vowelSubstitution);
|
|
|
|
if (string.Compare(ReplaceLettersWithSubStitutions(weakPassword, vowels, vowelSubstitution), password, System.StringComparison.OrdinalIgnoreCase) == 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
char[] qwerty = { 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P' };
|
|
char[] qwertySubstitution = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
|
|
|
|
if (string.Compare(ReplaceLettersWithSubStitutions(weakPassword, qwerty, qwertySubstitution), password, System.StringComparison.OrdinalIgnoreCase) == 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private static string ReplaceLettersWithSubStitutions(string password, char[] original, char[] substitution)
|
|
{
|
|
string newPassword = string.Empty;
|
|
|
|
foreach (char c in password)
|
|
{
|
|
bool numberAdded = false;
|
|
|
|
for (int q = 0; q < original.Length; q++)
|
|
{
|
|
if (c == original[q])
|
|
{
|
|
newPassword = newPassword + substitution[q];
|
|
numberAdded = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!numberAdded)
|
|
{
|
|
newPassword = newPassword + c;
|
|
}
|
|
}
|
|
|
|
return newPassword;
|
|
}
|
|
}
|
|
} |