Checking strings for a strong enough password [duplicate]
Asked Answered
W

1

26

Possible Duplicate:
Strong password regex
Need RegEx for password strength?

I was just wondering what the best way to search a string for certain criteria (password strength to be specific) could be accomplished.

So far I have a simple:

if(password.Length <= 7)
    {
        errorMessage = "Your password must be at least 8 characters.";
    }

I would like to be able to check for capital letters, but I am not sure what the method or procedure is. I have tried Googling, searching the website: http://msdn.microsoft.com, and searching the index of my C# book (C# Programming 3E, by Barbara Doyle), but I can't seem to find any.

I know I could try this...:

foreach(char c in password)
    {
        if(c!='A' || c!='B' || c!='C' || c!='D' ..... || c!='Z')
        {
            errorMessage = "Your password must contain at least one capital letter";
        }
    }

...But that would be extremely sloppy, and would have to be doubled to check for at least one lowercase letter. I am sure there is a better way to do this, or at least shorthand for the method I have shown above.

Also, I may decide to check the password for special characters (seems easier to do in the example above than with upper and lower case letters, so I may just use that for special characters, should I decide to make them necessary). If there is an easy (or proper) way to do that, I would love to have that knowledge, as well.

Anyway, thank you so much for any help anyone can give.

Webber answered 15/10, 2012 at 16:26 Comment(4)
This isn't an answer, but be sure you understand xkcd.com/936 and xkcd.com/792 And I also recommend reading codinghorror.com/blog/2010/12/… and searching Jeff's site for other related articles. Then look at Regular Expressions for verifying the appropriate length/complexity.Raimondo
Instead of a series of if...then clauses, you'd probably want to run the password through a regular expression. Take a look at this SO answer. I think it provides the Regular Expression that will help you.Sabinasabine
@DarinDimitrov Hey, thanks for that, I didn't see that link, because I didn't know to search for regex (although, I guess it's kind of obvious). My apologies, and thnx for the link!Webber
I very strongly disagree with the decision to close this question of as a duplicate by referencing only questions asking about regular expressions. The OP did not explicitly ask for a regex answer and some people may not find the use of regex to be the "best" answer since not everyone can easily understand regular expressions.Ablate
U
83

I can't take the credit, as I stole this from here

using System.Text;
using System.Text.RegularExpressions;

  public 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 = 0;

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

Note the use of regex for checking for upper case characters. This appears to be a decent approach, as it checks length, use of upper and lower case characters, numeric digits and special characters.

** Update **

I know the question is now closed, but I can add more explanation for VoidKing to understand some of the concepts.

A PasswordScore is returned from the CheckStrength method, which can be used as the condition for what to do next in your code.

Here's an untested demo of how the above code could be used:

String password = "MyDummy_Password"; // Substitute with the user input string
PasswordScore passwordStrengthScore = PasswordAdvisor.CheckStrength(password);

switch (passwordStrengthScore) {
    case PasswordScore.Blank:
    case PasswordScore.VeryWeak:
    case PasswordScore.Weak:
            // Show an error message to the user
            break;
    case PasswordScore.Medium:
    case PasswordScore.Strong:
    case PasswordScore.VeryStrong:
           // Password deemed strong enough, allow user to be added to database etc
           break;
}

Enums are used in this case as a means of classifying the strength of the password into human-readable groups. Keeps the code clean, and makes it obvious what is going on in the code.

Regarding the use of Regex's, if you're unfamiliar with the concept of them and how and when to use them, I suggest doing some research as these can be useful in many different scenarios for checking for patterns in strings. Perhaps start here.

Unbent answered 15/10, 2012 at 16:30 Comment(13)
Dude, you deserve some rep, just for how useful this is overall... Until now, I had no idea how they rated passwords on that scale... Thank you!Webber
How does this Regex work exactly? I'd like to be able to make my own. Am I right in assuming that it checks each character (and succeeding characters if the previous is a match) for matches within the regex string provided? (forgive me if I am not using regex correctly, grammatically speaking)Webber
Well, I was trying this, but I just don't know enough about this procedure. I just started pathing to (or using or whatever its called) external .cs files, and I can do that, but I can't seem to work with any of the data that this class is supposed to supply. It's never enough that I have code, I must also understand it in order to implement it into my applications, and I simply put, do not, here. What is ECMAScript? why enum? what kind of data is returned? (I found out I can't cast it into anything useable). Anyway, thanks for trying to help.Webber
I've updated the answer to help you further. Hope you find it useful.Unbent
I like it, although I would start the score at 0 to enforce even stronger passwords. As it is now 12345678 would be scored as medium strength, which I really don't agree with. :-)Promptitude
The password as Password@123 will produce PasswordScore as 6 which is not defined in enum. So the score must start with 0 to make it more reliable function.Koller
I had to take out the trailing/leading "/"s to get this to work.Delta
While this is good, it is essentially saying +1 for any of the following( length > 8, length > 12, has a lowercase alphabetical character, has an uppercase alphabetical character, has a digit, has a special character.) Because most of the logic is in regexes, it would be easily extendable to javascript. The only problem is that it doesn't check common words / consecutives etc. Not to say it's not a good solution, it just needs to be taken with a grain of... salt.Marriage
Wouldn't String.IsNullOrEmpty(password)make more sense than password.Length < 1?Jessie
@SumitGupta In fact there is a missing enum value, score must start at 1 otherwise password.Length < 4 and password.Length >= 8will both return a value of PasswordScore.VeryWeak. I added value PasswordScore.TooShort = 1 and returned this if password.Length < 4. All other enum values must be incremented by one. I edited the answer with my fixesSentinel
I "tried" to edit the answer with my fixes, but it seems that it was rejected :( if you copy/paste the code please read my above commentSentinel
I'd add + and =.Unclothe
@Sentinel I'm not sure >=8 being veryweak is a problem, but there's definitely a problem with passwords length 5,6 and 7 returning "Blank" (if they have no other qualities)Unclothe

© 2022 - 2024 — McMap. All rights reserved.