Go Back   CodingForums.com > :: Server side development > PHP > Post a PHP snippet

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 02-19-2011, 09:54 PM   PM User | #1
MRushton
New Coder

 
Join Date: Aug 2010
Posts: 45
Thanks: 0
Thanked 14 Times in 14 Posts
MRushton is an unknown quantity at this point
Password Validator

PHP Code:
  /**
   * Squiloople Framework
   *
   * LICENSE: Feel free to use and redistribute this code.
   *
   * @author Michael Rushton <michael@squiloople.com>
   * @link http://squiloople.com/
   * @category Squiloople
   * @package Models
   * @subpackage Validators
   * @version 1.0
   * @copyright Copyright © 2011 Michael Rushton
   */

  /**
   * Password Validator
   *
   * Generate salts and peppers, and validate and hash passwords
   */
  
final class PasswordValidator
  
{

    
/**
     * The password to validate
     *
     * @access private
     * @var string $_password
     */
    
private $_password;

    
/**
     * The key to be used for the HMAC
     *
     * @access private
     * @var string $_key
     */
    
private $_key;

    
/**
     * The salt
     *
     * @access private
     * @var string $_salt
     */
    
private $_salt;

    
/**
     * The pepper
     *
     * @access private
     * @var string $_pepper
     */
    
private $_pepper 'Sz^3X6r[UyvV~2]_0stT}8`uY7RwZx4{q|Q91W5';

    
/**
     * Set the password and the optional key
     *
     * @access public
     * @param string $password
     * @param string $key
     */
    
public function __construct($password$key '')
    {

      
// Set the password
      
$this->_password $password;

      
// Set the key
      
$this->_key $key;

    }

    
/**
     * Call the constructor fluently
     *
     * @access public
     * @static
     * @param string $password
     * @param string key
     * @return PasswordValidator
     */
    
public static function setPassword($password$key '')
    {
      return new 
self($password$key);
    }

    
/**
     * Check to see if the password is between 8 and 39 characters inclusive in length
     *
     * @access public
     * @var bool $key
     * @return bool
     */
    
public function isValidLength($key false)
    {

      
// Select which of the password or key is to be validated
      
$password $key $this->_key $this->_password;

      
// If the password is not between 8 and 39 characters inclusive in length then return false
      
if (!isset($password[7]) || isset($password[39]))
      {
        return 
false;
      }

      
// Otherwise return true
      
return true;

    }

    
/**
     * Check to see if the password is correctly formed
     *
     * @access public
     * @var bool key
     * @return bool
     */
    
public function isValidSyntax($key false)
    {

      
// Select which of the password or key is to be validated
      
$password $key $this->_key $this->_password;

      
// Return false if the password does not contain at least two characters of each case, two digits, and two other characters
      
if (!preg_match('/^(?=(?:.*[a-z]){2})(?=(?:.*[A-Z]){2})(?=(?:.*[0-9]){2})(?=(?:.*[^a-zA-Z0-9]){2})[\x20-\x7E]+$/sD'$password))
      {
        return 
false;
      }

      
// Otherwise return true
      
return true;

    }

    
/**
     * Perform the validation check on the password's length and syntax
     *
     * @access public
     * @var bool $key
     * @return bool
     */
    
public function isValid($key false)
    {

      
// If the length validation is successful then return the syntax validation result
      
if ($this->isValidLength($key))
      {
        return 
$this->isValidSyntax($key);
      }

      
// Otherwise return false
      
return false;

    }

    
/**
     * Set the salt
     *
     * @access public
     * @var string $salt
     * @return PasswordValidator
     */
    
public function setSalt($salt)
    {

      
// Set the salt
      
$this->_salt $salt;

      
// Return itself
      
return $this;

    }

    
/**
     * Generate and return a salt
     *
     * @access public
     * @var bool $reset
     * @return string
     */
    
public function getSalt($reset false)
    {

      
// If a salt has been set and a reset is not required then return the stored salt
      
if (!$reset && isset($this->_salt))
      {
        return 
$this->_salt;
      }

      
// Reset the salt
      
$salt '';

      
// Generate a random salt of 39 printable ASCII characters
      
for ($i 1$i <= 39; ++$i)
      {
        
$salt .= chr(mt_rand(32126));
      }

      
// Return the random salt
      
return $this->_salt $salt;

    }

    
/**
     * Return the pepper if required
     *
     * @access private
     * @var bool $key
     * @return string
     */
    
private function _getPepper($key false)
    {

      
// If the pepper is for the key then reverse it
      
$pepper $key strrev($this->_pepper) : $this->_pepper;

      
// Return the pepper portion
      
return substr($pepper039 strlen($key $this->_key $this->_password));

    }

    
/**
     * Generate and return a key
     *
     * @access private
     * @return string
     */
    
private function _getKey()
    {
      return 
$this->_getPepper(true) . $this->_key strrev($this->getSalt());
    }

    
/**
     * Hash the the salt, the password, and the pepper using SHA 512
     *
     * @access private
     * @return string
     */
    
private function _getHash()
    {
      return 
hash('sha512'$this->getSalt() . $this->_password $this->_getPepper());
    }

    
/**
     * Hash the password using an HMAC
     *
     * @access public
     * @return string
     */
    
public function getHash()
    {
      return 
hash('sha512'$this->_getKey() . $this->_getHash());
    }

  } 
To instantiate the password validator, either use the new keyword or call the class statically using PasswordValidator::setPassword() passing as the first parameter the password and as the optional second parameter the key.

PHP Code:
$passwordValidator = new PasswordValidator('swordfish''5W0rdF!$h'); 
To validate the password's length, which must be between 8 and 39 characters inclusive, call the isValidLength() method. To validate the password's syntax, which may only contain printable ASCII characters and must contain at least one lower-case alphabetic character, one upper-case alphabetic character, one digit, and one other character, call the isValidSyntax() method. To validate both, call the isValid() method. Passing a true parameter to any of these will validate the key.

PHP Code:
$passwordValidator PasswordValidator::setPassword('swordfish''SW0r!$H');

$passwordValidator->isValidLength(); // Returns true
$passwordValidator->isValidSyntax(); // Returns false
$passwordValidator->isValid()        // Returns false

$passwordValidator->isValidLength(true); // Returns true
$passwordValidator->isValidSyntax(true); // Returns true
$passwordValidator->isValid(true)        // Returns false 
To generate and return a salt, which is 39 characters in length and follows the same syntax rules as a valid password, call the getSalt() method. Generated salts are stored and returned if the method is called subsequent times. To generate a new salt pass a true parameter to the method.

PHP Code:
$passwordValidator->getSalt(); // Returns h&%G8\SThz7\P"$j>nB[Fpip{_rS{(f{2DEw>4R
$passwordValidator->getSalt(); // Returns h&%G8\SThz7\P"$j>nB[Fpip{_rS{(f{2DEw>4R
$passwordValidator->getSalt(true// Returns g0ow;+}5HnM*G ;|%!@?px$W4,DK)(3WbE*iK:1 
To set an established salt, primarily used when verifying against an already hashed password, use the setSalt() method passing as the only parameter the salt. Calling getSalt() after setting a salt this way will return the set salt unless a true parameter is passed to the former.

PHP Code:
$passwordValidator->setSalt('g0ow;+}5HnM*G ;|%!@?px$W4,DK)(3WbE*iK:1'); // Set the salt 
To return a hash of the password, which automatically generates a salt if one has not already been set and appends to the password a portion of the pepper to increase the total length to 78 characters, call the getHash() method. This uses an HMAC SHA 512 cryptographic hash function.

PHP Code:
$passwordValidator = new PasswordValidator('M1ch43L !$ 4w3S0m3''4m ! RiT3?');

if (
$passwordValidator->isValid() && $passwordValidator->isValid(true))
{
  
$hash $passwordValidator->getHash();
}

// Returns: 645995e153424619fb6f6194f6d60c323a678470388f91c4a84ae713d56b3d00e9feb46040f92df799b00e689c6a9e285eb378ac6475193e13e715e53a3cb854 
1. Is this the correct way to use an HMAC (I know there's a native hash_hmac function but decided on doing it my way instead)?
2. Should the key be longer than the 79 characters returned already? If so, should the same be true of the salt + password + pepper, and how many? 128?

Thanks.

Last edited by MRushton; 02-20-2011 at 10:41 PM..
MRushton is offline   Reply With Quote
Old 08-08-2012, 09:40 PM   PM User | #2
Arcticwarrio
Regular Coder

 
Arcticwarrio's Avatar
 
Join Date: May 2012
Location: UK
Posts: 623
Thanks: 16
Thanked 70 Times in 70 Posts
Arcticwarrio is on a distinguished road
i made this for adding salt to a password also for temporary passwords or pin numbers, could also be used for creating password reset keys

unique string chars or duplicated,
upper case, lowercase + numbers
Upper case + numbers
Numbers only

feel free to message me if you need help modifying it for your own needs
could easily be altered to generate lottery numbers etc

function:
PHP Code:
function GenCode($len,$type 1,$uni 0){
    
//Written by Arcticwarrio - 08-August-2012
    //http://www.codingforums.com/member.php?u=147238
    //GenCode(length of string,$type = 1, 2 or 3,unique chars?)
    //Unique Switch 1 for on 0 or ommited for off
    //Type Switch 1 = a-z, A-Z, 0-9     Usage: GenCode(8); or GenCode(8,1);
    //Type Switch 2 = A-Z, 0-9          Usage: GenCode(10,2);
    //Type Switch 2 = 0-9               Usage: GenCode(4,3);

    //Reset Function
    
$code ='';
    
//Array of chars to choose from, feel free to add more arrays
    
$codestring['1'] = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0');
    
$codestring['2'] = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9','0');
    
$codestring['3'] = array('1','2','3','4','5','6','7','8','9','0');
    
    
//see if the string should contain unique chars
    
if ($uni == 1){
        
//check if theres enough chars to have a unique string
        
if ($len count($codestring[$type])-1){ echo "error length too long for unique string"; exit;}
        
//loop for lenght of $len NOT allowing duplicate chars
        
for ($i=1$i<=$len$i++){
            
//add char from chosen array to the end of the variable $code
            
$tempx $codestring[$type][rand(0,count($codestring[$type])-1)];
            if (
strstr($code$tempx) != false){
                
$i--;
            }else{
                
$code .= $tempx;
            }
        }
 
    }else{
        
//loop for lenght of $len allowing duplicate chars
        
for ($i=1$i<=$len$i++){
            
//add char from chosen array to the end of the variable $code
            
$code .= $codestring[$type][rand(0,count($codestring[$type])-1)];
        }
    }
        
//send $code back to where GenCode() was called from
    
return $code;

__________________
There are 10 types of people on CodingForums,
Those who understand Binary and those who dont.
Arcticwarrio 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 07:05 AM.


Advertisement
Log in to turn off these ads.