Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 01-21-2013, 08:27 PM   PM User | #1
doubledee
Regular Coder

 
doubledee's Avatar
 
Join Date: Mar 2011
Location: Arizona
Posts: 617
Thanks: 19
Thanked 0 Times in 0 Posts
doubledee has a little shameless behaviour in the past
Setting Password Strength

I could use some advice on what is a *reasonable* approach on checking the Password Strength when users register or re-set their password on my website.

Security is extremely important to me, but there are some constraints as well, including...

1.) I don't want to make my website so difficult to use that it chases away the average (and even power) users

2.) I don't have months and years to read up on "Log-In Theory" and come up with some master scheme

My goal for this thread, is to start off with a reasonable approach to checking Password Strength, and then over the next few months come up with a more robust approach, which will likely use "Pass Phrases" among other things.

(Please no "flame wars" on this topic.)

Below is a snippet of code that checks for Password Strength in my "change-password.php" script....
PHP Code:

    
// ****************************
    // Check Password Strength.        *
    // ****************************

    // Check Password Length.
    
if (strlen($newPass1) < 8){
        
$errors['newPass'] = 'Password must be at least 8 Characters.';
    }

    
// Check for Uppercase Letter.
    
if (empty($errors)){
        if (
strtolower($newPass1) == $newPass1){
            
$errors['newPass'] = 'Password must have at least 1 Uppercase Letter.';
        }
    }

    
// Check for Lowercase Letter.
    
if (empty($errors)){
        if (
strtoupper($newPass1) == $newPass1){
            
$errors['newPass'] = 'Password must have at least 1 Lowercase Letter.';
        }
    }

    
// Check for Number.
    
if (empty($errors)){
        if (!
preg_match("#[0-9]+#"$newPass1)){
            
$errors['newPass'] = 'Password must have at least 1 Number.';
        }
    }

    
// Fou-Lu makes it sound like I don't need this section.
    // Check for Illegal-Characters.
    
if (empty($errors)){
        if (
preg_match("#[\,\"\']+#"$newPass1)){
            
$errors['newPass'] = 'Password may not use Comma, Single or Double Quotes.';
        }
    }


    
// Not so sure about this one...
    // Check for Special-Character.
    
if (empty($errors)){
        if (!
preg_match("#[\~\`\!\@\#\$\%\^\&\*\(\)\_\-\+\=\{\}\[\]\|\:\;\<\>\.\?\/\\\\]+#"$newPass1)){
//                    if (!preg_match("#[\W_]+#", $newPass1)){
                            
$errors['newPass'] = 'Password must have at least 1 Special Character.';
        }
    }


    if (empty(
$errors)){
        
// Strong Password.
        
$newPass $newPass1;

    }else{
        
// Weak Password.
        // Drop through to display Errors.

    
}//End of CHECK PASSWORD STRENGTH 

BTW, I don't know OOP yet, and I'd prefer to learn how to make a procedural home-grown Password-Strength-Checker for now.

Sincerely,


Debbie
doubledee is offline   Reply With Quote
Old 01-21-2013, 09:00 PM   PM User | #2
TFlan
New Coder

 
Join Date: Dec 2012
Location: USA
Posts: 82
Thanks: 3
Thanked 17 Times in 17 Posts
TFlan is an unknown quantity at this point
Your bestfriend when it comes to password strength validation/test is preg_match()

PHP Code:
$minLength 8;
$maxLength 20;

// $passwordStr = '#.*^(?=.{'.$minLength.','.$maxLength.'})(?=.*[a-z])(?=.*[A-Z]).*$#';                                        // Letters Only
// $passwordStr = '#.*^(?=.{'.$minLength.','.$maxLength.'})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).*$#';                // Letters & Numbers
$passwordStr '#.*^(?=.{'.$minLength.','.$maxLength.'})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*\W).*$#';        // Letters, Numbers, & Symbols

if(preg_match($passwordStr$string)){
    
// password passes strength requirements

The above code tests if '$string' matches the pattern (or password minimum strength) and returns true|false

You can take the above code and manipulate it in several ways.

IE: Reassign each strength "tier" (I will call it tier) string to a unique string. Then test the '$string' against each pattern, and when it catches a match, return the strength index (Weak, Average, Good - or whatever you assign to each strength tier
TFlan is offline   Reply With Quote
Old 01-21-2013, 09:07 PM   PM User | #3
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,451 Times in 2,420 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
Good things to keep in mind: length + complexity.
At least one lower case
At least one upper case
At least one special character
At least x characters (8 sounds sufficient) excluding spaces
No repeating characters (3x characters or numbers in a row; I'd let them get away with 2x, but I don't think there's any "word" that conatains 3x).

There are many more other things that can be done. No dictionary words, no "like" word replacements (and = &, to = 2, etc, late = l8). Password phrases would be easy: minimum characters: 25.
Average users will not appreciate the pass phrases. Despite being a lot better and typically much easier to remember.

OO would only benefit by writing wrappers. So the ruleset can be refined by adding more filters to perform a specific task to check. Procedural can do that as well with functions. But the OO implementation is the same basic logic flow as that of the procedural code.
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php
Fou-Lu is offline   Reply With Quote
Old 01-21-2013, 09:36 PM   PM User | #4
doubledee
Regular Coder

 
doubledee's Avatar
 
Join Date: Mar 2011
Location: Arizona
Posts: 617
Thanks: 19
Thanked 0 Times in 0 Posts
doubledee has a little shameless behaviour in the past
Quote:
Originally Posted by TFlan View Post
Your bestfriend when it comes to password strength validation/test is preg_match()
The reason I do NOT want one humongous Regex, is that I want to provide Error Messages for each way the Password fails, as demonstrated in my code above...


Debbie
doubledee is offline   Reply With Quote
Old 01-21-2013, 09:42 PM   PM User | #5
doubledee
Regular Coder

 
doubledee's Avatar
 
Join Date: Mar 2011
Location: Arizona
Posts: 617
Thanks: 19
Thanked 0 Times in 0 Posts
doubledee has a little shameless behaviour in the past
Quote:
Originally Posted by Fou-Lu View Post
Good things to keep in mind: length + complexity.
At least one lower case
At least one upper case
At least one special character
At least x characters (8 sounds sufficient) excluding spaces
So is the code sample I provided above sufficient for now?


Quote:
No repeating characters (3x characters or numbers in a row; I'd let them get away with 2x, but I don't think there's any "word" that conatains 3x).
How would I do that?


Quote:
There are many more other things that can be done. No dictionary words, no "like" word replacements (and = &, to = 2, etc, late = l8). Password phrases would be easy: minimum characters: 25.
Average users will not appreciate the pass phrases. Despite being a lot better and typically much easier to remember.
Well, Fou-Lu, that is what I'd like to do with time...

Once this current version (v2.0) is done shortly, then I'll go read up on the whole topic of "Password Strength" and try to come up with something more "2013" than "2001".

I'm sure there is a way to require stronger Passwords/Pass-Phrases WITHOUT driving the average User crazy.

But I don't know what that is currently?!


Quote:
OO would only benefit by writing wrappers. So the ruleset can be refined by adding more filters to perform a specific task to check. Procedural can do that as well with functions. But the OO implementation is the same basic logic flow as that of the procedural code.
What I meant was I believe there are some "super-duper Password Strength classes" already out there for free use, but since I don't know OOP, and don't want to know OOP for v2.0, it wouldn't be of help.

So it sounds like the code I provided would be a good place to start, right? (Other than I should add in a way to make sure someone doesn't type "D*****D**1")


Debbie
doubledee is offline   Reply With Quote
Old 01-23-2013, 01:40 AM   PM User | #6
doubledee
Regular Coder

 
doubledee's Avatar
 
Join Date: Mar 2011
Location: Arizona
Posts: 617
Thanks: 19
Thanked 0 Times in 0 Posts
doubledee has a little shameless behaviour in the past
Still there, Fou-Lu?


Debbie
doubledee is offline   Reply With Quote
Old 01-23-2013, 01:09 PM   PM User | #7
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,451 Times in 2,420 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
Repeating characters can be detected using regex or by using iteration of the string and manually counting them. If you're going to iterate, than you might as well do all the other comparisons char by char as well since you need to evaluate every character anyway.
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php
Fou-Lu is offline   Reply With Quote
Old 01-24-2013, 01:52 AM   PM User | #8
doubledee
Regular Coder

 
doubledee's Avatar
 
Join Date: Mar 2011
Location: Arizona
Posts: 617
Thanks: 19
Thanked 0 Times in 0 Posts
doubledee has a little shameless behaviour in the past
Quote:
Originally Posted by Fou-Lu View Post
Repeating characters can be detected using regex or by using iteration of the string and manually counting them. If you're going to iterate, than you might as well do all the other comparisons char by char as well since you need to evaluate every character anyway.
Is it expensive to iterate character by character through a password?

Any reasons why you would want to avoid this approach? (It seems like it might be the better way?!)


Debbie
doubledee is offline   Reply With Quote
Old 01-24-2013, 02:17 AM   PM User | #9
AndrewGSW
Senior Coder

 
Join Date: Apr 2011
Location: London, England
Posts: 2,120
Thanks: 15
Thanked 354 Times in 353 Posts
AndrewGSW will become famous soon enough
Quote:
Is it expensive to iterate character by character through a password?
Unless your password is huge I wouldn't worry about the expense.
__________________
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
Validate your HTML and CSS
AndrewGSW is offline   Reply With Quote
Old 01-24-2013, 03:40 AM   PM User | #10
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,451 Times in 2,420 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
I guess that depends on what you compare it to. Using iteration will increase its weight lineally based on the length of the string. Shorter it is, the better it will perform even compared to what is here. The longer it is, the worse it will perform, even compared to what is here.
Doing all that needs to get done, I would expect you'd see better performance on average using regex. Overall it'll be about the same. If I have a password of 'aaaa' and allow all rules to evaluate, than iteration will win. If I have a password of 'this is my passphrase which is quite long', than regex will win.
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php
Fou-Lu is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 06:16 PM.


Advertisement
Log in to turn off these ads.