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