Overview

Namespaces

  • PHP
  • PHPassLib
    • Application
    • Exception
    • Hash
    • Test
      • Application
      • Hash

Classes

  • BCrypt
  • BSDiCrypt
  • DESCrypt
  • MD5Crypt
  • PBKDF2
  • Portable
  • SHA1Crypt
  • SHA256Crypt
  • SHA512Crypt
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * PHP Password Library
  4:  *
  5:  * @package PHPassLib\Hashes
  6:  * @author Ryan Chouinard <rchouinard@gmail.com>
  7:  * @copyright Copyright (c) 2012, Ryan Chouinard
  8:  * @license MIT License - http://www.opensource.org/licenses/mit-license.php
  9:  * @version 3.0.0-dev
 10:  */
 11: 
 12: namespace PHPassLib\Hash;
 13: 
 14: use PHPassLib\Hash;
 15: use PHPassLib\Utilities;
 16: use PHPassLib\Exception\InvalidArgumentException;
 17: 
 18: /**
 19:  * SHA-1 Crypt Module
 20:  *
 21:  * This module provides the SHA-1 Crypt algorithm which was introduced by
 22:  * NetBSD in 2004.
 23:  *
 24:  * Supported parameters:
 25:  *
 26:  * <ul>
 27:  *   <li><b>rounds:</b> Optional number of rounds to use. Must be an integer
 28:  *   between 1 and 4294967295 inclusive. Defaults to 40000.</li>
 29:  *
 30:  *   <li><b>salt:</b> Optional salt string. If provided, it must be a string
 31:  *   0 - 64 characters in length, containing only characters in the regex range
 32:  *   [./0-9A-Za-z]. It is highly recommended that this parameter be left blank,
 33:  *   in which case the library will generate a suitable salt for you.</li>
 34:  * </ul>
 35:  *
 36:  * @package PHPassLib\Hashes
 37:  * @author Ryan Chouinard <rchouinard@gmail.com>
 38:  * @copyright Copyright (c) 2012, Ryan Chouinard
 39:  * @license MIT License - http://www.opensource.org/licenses/mit-license.php
 40:  */
 41: class SHA1Crypt implements Hash
 42: {
 43: 
 44:     /**
 45:      * Generate a config string from an array.
 46:      *
 47:      * @param array $config Array of configuration options.
 48:      * @return string Configuration string.
 49:      * @throws InvalidArgumentException Throws an InvalidArgumentException if
 50:      *     any passed-in configuration options are invalid.
 51:      */
 52:     public static function genConfig(array $config = array ())
 53:     {
 54:         $defaults = array (
 55:             'rounds' => 40000,
 56:             'salt' => Utilities::encode64(Utilities::genRandomBytes(6)),
 57:         );
 58:         $config = array_merge($defaults, array_change_key_case($config, CASE_LOWER));
 59: 
 60:         $string = '*1';
 61:         if (self::validateOptions($config)) {
 62:             $string = sprintf('$sha1$%d$%s', $config['rounds'], $config['salt']);
 63:         }
 64: 
 65:         return $string;
 66:     }
 67: 
 68:     /**
 69:      * Parse a config string into an array.
 70:      *
 71:      * @param string $config Configuration string.
 72:      * @return array Array of configuration options or false on failure.
 73:      */
 74:     public static function parseConfig($config)
 75:     {
 76:         $options = false;
 77:         $matches = array ();
 78:         if (preg_match('/^\$sha1\$(\d+)\$([\.\/0-9A-Za-z]{0,64})\$?/', $config, $matches)) {
 79:             $options = array (
 80:                 'rounds' => (int) $matches[1],
 81:                 'salt' => $matches[2],
 82:             );
 83: 
 84:             try {
 85:                 self::validateOptions($options);
 86:             } catch (InvalidArgumentException $e) {
 87:                 $options = false;
 88:             }
 89:         }
 90: 
 91:         return $options;
 92:     }
 93: 
 94:     /**
 95:      * Generate a password hash using a config string.
 96:      *
 97:      * @param string $password Password string.
 98:      * @param string $config Configuration string.
 99:      * @return string Returns the hash string on success. On failure, one of
100:      *     *0 or *1 is returned.
101:      */
102:     public static function genHash($password, $config)
103:     {
104:         $hash = ($config == '*0') ? '*1' : '*0';
105: 
106:         $config = self::parseConfig($config);
107:         if (is_array($config)) {
108:             $rounds = $config['rounds'];
109:             $checksum = hash_hmac('sha1', $config['salt'] . '$sha1$' . $rounds--, $password, true);
110:             if ($rounds) {
111:                 do {
112:                     $checksum = hash_hmac('sha1', $checksum, $password, true);
113:                 } while (--$rounds);
114:             }
115: 
116:             $tmp = '';
117:             foreach (array (2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, 17, 16, 15, 0, 19, 18) as $offset) {
118:                 $tmp .= $checksum[$offset];
119:             }
120:             $checksum = Utilities::encode64($tmp);
121: 
122:             $hash = self::genConfig($config) . '$' . $checksum;
123:         }
124: 
125:         return $hash;
126:     }
127: 
128:     /**
129:      * Generate a password hash using a config string or array.
130:      *
131:      * @param string $password Password string.
132:      * @param string|array $config Optional config string or array of options.
133:      * @return string Returns the hash string on success. On failure, one of
134:      *     *0 or *1 is returned.
135:      * @throws InvalidArgumentException Throws an InvalidArgumentException if
136:      *     any passed-in configuration options are invalid.
137:      */
138:     public static function hash($password, $config = array ())
139:     {
140:         if (is_array($config)) {
141:             $config = self::genConfig($config);
142:         }
143: 
144:         return self::genHash($password, $config);
145:     }
146: 
147:     /**
148:      * Verify a password against a hash string.
149:      *
150:      * @param string $password Password string.
151:      * @param string $hash Hash string.
152:      * @return boolean Returns true if the password matches, false otherwise.
153:      */
154:     public static function verify($password, $hash)
155:     {
156:         return ($hash === self::hash($password, $hash));
157:     }
158: 
159:     /**
160:      * @param array $options
161:      * @return boolean
162:      * @throws InvalidArgumentException
163:      */
164:     protected static function validateOptions(array $options)
165:     {
166:         $options = array_change_key_case($options, CASE_LOWER);
167:         foreach ($options as $option => $value) switch ($option) {
168: 
169:             case 'rounds':
170:                 if ($value < 1 || $value > 4294967295) {
171:                     throw new InvalidArgumentException('Invalid rounds parameter');
172:                 }
173:                 break;
174: 
175:             case 'salt':
176:                 if (!preg_match('/^[\.\/0-9A-Za-z]{0,64}$/', $value)) {
177:                     throw new InvalidArgumentException('Invalid salt parameter');
178:                 }
179:                 break;
180: 
181:             default:
182:                 break;
183: 
184:         }
185: 
186:         return true;
187:     }
188: 
189: }
190: 
PHP Password Library API documentation generated by ApiGen 2.8.0