/** * Generate a config string from an array. * * @param array $config Array of configuration options. * @return string Configuration string. * @throws InvalidArgumentException Throws an InvalidArgumentException if * any passed-in configuration options are invalid. */ public static function genConfig(array $config = array()) { $defaults = array('salt' => Utilities::encode64(Utilities::genRandomBytes(1))); $config = array_merge($defaults, array_change_key_case($config, CASE_LOWER)); $string = '*1'; if (self::validateOptions($config)) { $string = $config['salt']; } return $string; }
/** * Generate a config string from an array. * * @param array $config Array of configuration options. * @return string Configuration string. * @throws InvalidArgumentException Throws an InvalidArgumentException if * any passed-in configuration options are invalid. */ public static function genConfig(array $config = array()) { $defaults = array('rounds' => 80000, 'salt' => Utilities::encode64(Utilities::genRandomBytes(12))); $config = array_merge($defaults, array_change_key_case($config, CASE_LOWER)); $string = '*1'; if (self::validateOptions($config)) { $rounds = ''; if ($config['rounds'] != 5000) { $rounds = sprintf('rounds=%d$', $config['rounds']); } $string = sprintf('$5$%s%s', $rounds, $config['salt']); } return $string; }
/** * Parse a config string into an array. * * @param string $config Configuration string. * @return array Array of configuration options or false on failure. */ public static function parseConfig($config) { $options = false; $matches = array(); if (preg_match('/^_([\\.\\/0-9A-Za-z]{4})([\\.\\/0-9A-Za-z]{4})/', $config, $matches)) { $options = array('rounds' => (int) Utilities::decodeInt24($matches[1]), 'salt' => $matches[2]); try { self::validateOptions($options); } catch (InvalidArgumentException $e) { $options = false; } } return $options; }
/** * Generate a password hash using a config string. * * @param string $password Password string. * @param string $config Configuration string. * @return string Returns the hash string on success. On failure, one of * *0 or *1 is returned. */ public static function genHash($password, $config) { $hash = $config == '*0' ? '*1' : '*0'; $config = self::parseConfig($config); if (is_array($config)) { $rounds = 1 << $config['rounds']; $checksum = md5($config['salt'] . $password, true); do { $checksum = md5($checksum . $password, true); } while (--$rounds); $hash = self::genConfig($config) . Utilities::encode64($checksum); } return $hash; }
/** * @param string $input * @return string */ protected static function genSalt($input = null) { if (!$input) { $input = Utilities::genRandomBytes(16); } $count = strlen($input); $atoi64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; $output = ''; $i = 0; do { $c1 = ord($input[$i++]); $output .= $atoi64[$c1 >> 2]; $c1 = ($c1 & 0x3) << 4; if ($i >= $count) { $output .= $atoi64[$c1]; break; } $c2 = ord($input[$i++]); $c1 |= $c2 >> 4; $output .= $atoi64[$c1]; $c1 = ($c2 & 0xf) << 2; $c2 = ord($input[$i++]); $c1 |= $c2 >> 6; $output .= $atoi64[$c1]; $output .= $atoi64[$c2 & 0x3f]; } while (1); return $output; }
/** * Generate a password hash using a config string. * * @param string $password Password string. * @param string $config Configuration string. * @return string Returns the hash string on success. On failure, one of * *0 or *1 is returned. */ public static function genHash($password, $config) { $hash = $config == '*0' ? '*1' : '*0'; $config = self::parseConfig($config); if (is_array($config)) { $rounds = $config['rounds']; $checksum = hash_hmac('sha1', $config['salt'] . '$sha1$' . $rounds--, $password, true); if ($rounds) { do { $checksum = hash_hmac('sha1', $checksum, $password, true); } while (--$rounds); } $tmp = ''; 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) { $tmp .= $checksum[$offset]; } $checksum = Utilities::encode64($tmp); $hash = self::genConfig($config) . '$' . $checksum; } return $hash; }
/** * @param string $input * @return string */ protected static function genSalt($input = null) { if (!$input) { $input = Utilities::genRandomBytes(16); } return Utilities::altBase64Encode($input); }