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