validators

Password Validator

<?php

  /**
   * 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 © 2011 Michael Rushton
   */

  // Define the namespace
  namespace Models\Validators;

  /**
   * Password Validator
   *
   * Hash or validate passwords
   */
  final class PasswordValidator
  {

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

    /**
     * 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
     *
     * @access public
     * @param string $password
     */
    public function __construct($password = '')
    {
      $this->_password = $password;
    }

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

    /**
     * Return the password
     *
     * @access public
     * @return string
     */
    public function getPassword()
    {
      return $this->_password;
    }

    /**
     * Create a random password
     *
     * @access public
     * @return \Models\Validators\PasswordValidator
     */
    public function randomizePassword()
    {

      // If the password is incorrectly formed then randomize again
      if (!$this->isValid($this->_password = substr($this->getSalt(true), 0, 8)))
      {
        $this->randomizePassword();
      }

      // Reset the salt
      $this->_salt = null;

      // Return the object
      return $this;

    }

    /**
     * Validate the password
     *
     * @access public
     * @param bool|string $new
     * @return bool
     */
    public function isValid($new = false)
    {

      // The password must contain at least one character of each case, one digit, and be between 8 and 39 characters inclusive in length
      if (!preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[\x20-\x7E]{8,39}$/D', $new ?: $this->_password))
      {
        return false;
      }

      // Otherwise return true
      return true;

    }

    /**
     * Set the salt
     *
     * @access public
     * @param string $salt
     * @return \Models\Validators\PasswordValidator
     */
    public function setSalt($salt)
    {

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

      // Return itself
      return $this;

    }

    /**
     * Generate and return a salt
     *
     * @access public
     * @param 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(32, 126));
      }

      // If the salt does not have the correct syntax then regenerate
      if (!$this->isValid($salt))
      {
        $this->getSalt(true);
      }

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

    }

    /**
     * Return the pepper portion
     *
     * @access private
     * @return string
     */
    private function _getPepper()
    {
      return substr($this->_pepper, 0, 39 - strlen($this->_password));
    }

    /**
     * Hash the password
     *
     * @access private
     * @return string
     */
    private function _getHash()
    {
      return hash('sha384', $this->getSalt() . $this->_password . $this->_getPepper());
    }

    /**
     * Hash the password using an HMAC-inspired hash
     *
     * @access public
     * @return string
     */
    public function getHash()
    {
      return hash('sha512', substr(strrev($this->_pepper), 0, 20) . $this->_getHash());
    }

  }

Read More

Tags: ,

Saturday, February 19th, 2011 PHP No Comments