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