views:

199

answers:

6

A customer asked me to prevent users from typing common passwords, but permit them to use only alphanumeric passwords.

Do you know a regular expression to use in the built in PasswordStrengthRegularExpression option?

Edit: I know is pretty vague, and that what I told the client. The definition is something like

  • Do not allow the same character more that 3 consecutive times.(1111, 2222, etc)
  • Do not allow ascending or descending trends (12345, abcde, 6543, etc.)
+1  A: 

How about this one?

passwordStrengthRegularExpression=" @\"(?=.{6,})(?=(.*\d){1,})(?=(.*\W){1,})"

Validates the password meets the following criteria:

  • Is greater than seven characters.
  • Contains at least one digit.
  • Contains at least one special (non-alphanumeric) character.

http://msdn.microsoft.com/en-us/library/system.web.security.membership.passwordstrengthregularexpression.aspx

Robert Harvey
The `{1,}` are redundant (and might even slow things down): you only care that it matches once, not that it consumes as many copies of the match as possible. Also, your quotes are messed up; your string starts with `" @\"`, when I think you mean for it to start with `@"`.
Antal S-Z
@Antal: The code above is not C#, it is an XML attribute.
Robert Harvey
Guh, disregard that—I've never even *used* C#, I just answered a regex question on it and had it on the brain. Wow. My bad.
Antal S-Z
But the point about the `{1,}` is still valid. I know that's how it appears in the docs, but it's wrong. Whoever wrote those docs had very weak regex-fu.
Alan Moore
Not what I asked for. Sorry.
Eduardo Molteni
A: 

try this:

passwordStrengthRegularExpression="^\S*([a-zA-Z0-9]{1,10})$"
Ratan
A: 

This may be of some help:

http://info4tech.wordpress.com/2007/08/07/regular-expressions-for-strong-password-in-aspnet/

David
Not what I asked for. Sorry.
Eduardo Molteni
A: 

You can assert a minimum level of complexity; e. g. "at least one uppercase, one lowercase letter, one digit, minimum length 6 characters, only alphanumeric characters" could be written as

 ^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[A-Za-z0-9]{6,}$
Tim Pietzcker
Not what I asked for. Sorry.
Eduardo Molteni
+1  A: 

I'm not sure if a regular expression can handle the requirement, but a function just may be more readable anyway. Something like the below will eliminate anything with three consecutive equal characters or three consecutive characters that are follow an ascending or descending pattern of 1 (letters or numbers).

static bool IsPasswordRelativelyStrong(string input)
{
    for (int i = 2; i < input.Length; i++)
    {
        if (input[i] == input[i - 1] - 1 && input[i - 1] == input[i - 2] - 1)
            return false;
        else if (input[i] == input[i - 1] + 1 && input[i - 1] == input[i - 2] + 1)
            return false;
        else if (input[i] == input[i - 1] && input[i - 1] == input[i - 2])
            return false;
    }

    return true;
}

So given the following array

string[] passwords = { "123456", "abcde", "654321", "111223", "11223344" };

Only the final one passes. The function could be expanded to consider whether or not you allow and/or require non-alphanumeric characters and whether a password must exceed a minimum length requirement.

Anthony Pegram
That's what I have in mind. Just didn't want to reinvent the wheel. Thanks
Eduardo Molteni
+1  A: 

That's asking way too much from a regex. You could cover the repeated characters thing easily enough:

^(?:(.)(?!\1\1)){6,}$

But the only way to disallow runs of sequential characters would be to enumerate all the possibilities:

^(?:(?!123|234|345|456|567|678|789).)*$

...ad infinitum. I think the best you can do is require a complex mix of character types--for example, at least two each of uppercase letters, lowercase letters and digits:

^(?=(?:[^0-9]*[0-9]){2})
 (?=(?:[^A-Z]*[A-Z]){2})
 (?=(?:[^a-z]*[a-z]){2})
 (?:([A-Za-z0-9])(?!\1\1)){6,}$

That will force the users to be a little creative.

Alan Moore
Thanks for your answer.
Eduardo Molteni