/////////////////////////////// Updated Post Below ////////////////////////////
This question has received a lot of hits, more than I ever thought it would have on such a basic topic. So, I thought I would update people on what I am doing. Also I keep reading in the comments that I am storing passwords as plain text. Just to clarify I am not.
My updated validation function :
public function is_password($str) {
if (strlen($str) < 10) { // Less then 10
$this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
return FALSE;
} elseif (strlen($str) > 100) { // Greater then 100
$this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
return FALSE;
} elseif (!preg_match("#[0-9]+#", $str)) { // At least 1 number
$this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
return FALSE;
} elseif (!preg_match("#[a-z]+#", $str)) { // At least 1 letter
$this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
return FALSE;
} elseif (!preg_match("#[A-Z]+#", $str)) { // At least 1 capital
$this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
return FALSE;
} elseif (!preg_match("#\W+#", $str)) { // At least 1 symbol
$this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
return FALSE;
} else {
return TRUE; // No errors
}
}
Each time it returns FALSE
, I always tell them the entire password need.
Just to answer some of the questions as to why it is so long :
Why not so long? People at my job that I talk to use sentences. Very long ones at that.
How am I hashing my passwords? / Why use 100 characters? -> just use better hashing algorithm
For PHP, I am using the best there is for this language. I am using this library which is the PHP 5.5 equivalence of the new password hashing API created by Anthony Ferrara. My reasoning for this hashing use is simple, very high demand on the CPU (if you ever test it out on a Linux/Windows box CPU usage is at 100%). Also, the algorithm is very scalable due to the cost factor the higher the cost the more grueling the task is for the CPU to log a person in. Last I "Tested", I put the cost to 24. An entire hour passed for me to try and login and I got a PHP time out error before I even got past the login screen (this was a foolish cost factor). A study done by Jeremi Gosney (THIS IS THE PDF DOWNLOAD OF THE REPORT) which tested the strength of this function compared to other more popular ones (yes, more popular) concluded that even with 25 - GPUs, while using bcrypt at a cost of 5, password hashing is the last of your concerns. I use a cost of 17...
My function if any one is interested (The parts that pertain to this subject at least) :
public function create_user($value) {
$this -> CI = get_instance();
$this -> CI -> load -> library('bcrypt');
foreach ($value as $k => $v) {// add PDO place holder to the keys
$vals[":$k"] = $v;
}
$vals[":password"] = $this -> CI -> bcrypt -> password_hash($vals[":password"], PASSWORD_BCRYPT, array("cost" => 17)); // Take old $vals[":password"] and run it through bcrypt to come up with the new $vals[":password"]
Hopefully this question helps others out there.
/////////////////////////////// Original Post Below ////////////////////////////
I'm currently working on a new project, and an issue struck me.
Is it it safe to disclose your password requirements? If so, why is it safe?
I have a function that does validation on a password and each step shows the user why validation does not work.
Here is my function:
public function is_password($str) {
if (strlen($str) < 10) {
$this -> set_message('is_password', 'Password too short.');
return FALSE;
} elseif (strlen($str) > 100) {
$this -> set_message('is_password', 'Password is too long.');
return FALSE;
} elseif (!preg_match("#[0-9]+#", $str)) {
$this -> set_message('is_password', 'Password must include at least one number.');
return FALSE;
} elseif (!preg_match("#[a-z]+#", $str)) {
$this -> set_message('is_password', 'Password must contain at least one letter.');
return FALSE;
} elseif (!preg_match("#[A-Z]+#", $str)) {
$this -> set_message('is_password', 'Password must contain at least one capital letter.');
return FALSE;
} elseif (!preg_match("#\W+#", $pwd)) {
$this -> set_message('is_password', 'Password must include at least one symbol.');
return FALSE;
} else {
return TRUE;
}
}
My thought on this is, if we let the "user" / attacker know what my passwords consist of wouldn't it be easier for the attacker to know? I know security through obscurity is not a best practice, but could it be a strong argument in this situation?
I would like to know if I am going about this in the right way. Any help would be great.