mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-05 09:41:40 +09:00
150 lines
5.2 KiB
PHP
150 lines
5.2 KiB
PHP
<?php
|
|
|
|
// PHP implementation of several vendor-specific password hashing functions.
|
|
|
|
class VendorPass
|
|
{
|
|
// MySQL's OLD_PASSWORD() function.
|
|
// Minor modification of the code written by Dustin Fineout, 10/9/2009
|
|
// Source: http://stackoverflow.com/questions/260236/mysql-hashing-function-implementation
|
|
|
|
public static function mysql_old_password($password)
|
|
{
|
|
$password = strval($password);
|
|
$length = strlen($password);
|
|
$nr1 = 0x50305735; $nr2 = 0x12345671; $add = 7; $tmp = null;
|
|
for ($i = 0; $i < $length; $i++) {
|
|
$byte = substr($password, $i, 1);
|
|
if ($byte === ' ' || $byte === "\t") continue;
|
|
$tmp = ord($byte);
|
|
$nr1 ^= (($nr1 << 8) & 0x7FFFFFFF) + ((($nr1 & 63) + $add) * $tmp);
|
|
$nr2 += (($nr2 << 8) & 0x7FFFFFFF) ^ $nr1;
|
|
$add += $tmp;
|
|
}
|
|
return sprintf("%08x%08x", $nr1 & 0x7FFFFFFF, $nr2 & 0x7FFFFFFF);
|
|
}
|
|
|
|
// MySQL's PASSWORD() function.
|
|
|
|
public static function mysql_new_password($password)
|
|
{
|
|
return '*' . strtoupper(sha1(sha1($password, true)));
|
|
}
|
|
|
|
// MS SQL Server's PWDENCRYPT() function.
|
|
|
|
public static function mssql_pwdencrypt($password, $salt = null)
|
|
{
|
|
if ($salt !== null && strlen($salt) === 54)
|
|
{
|
|
$salt = substr($salt, 6, 8);
|
|
}
|
|
else
|
|
{
|
|
$salt = strtoupper(str_pad(dechex(mt_rand(0, 65535)), 4, '0') .
|
|
str_pad(dechex(mt_rand(0, 65535)), 4, '0'));
|
|
}
|
|
$password = mb_convert_encoding($password, 'UTF-16LE', 'UTF-8');
|
|
return '0x0100' . strtoupper($salt . sha1($password . pack('H*', $salt)));
|
|
}
|
|
|
|
// Drupal's SHA512-based password hashing algorithm.
|
|
|
|
public static function drupal($password, $salt = null)
|
|
{
|
|
$itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
if ($salt !== null && strlen($salt) > 12)
|
|
{
|
|
$iterations = intval(strpos($itoa64, substr($salt, 3, 1)));
|
|
$salt = substr($salt, 4, 8);
|
|
}
|
|
else
|
|
{
|
|
$iterations = 15;
|
|
$salt = Rhymix\Framework\Security::getRandom(8, 'hex');
|
|
}
|
|
$count = 1 << $iterations;
|
|
$hash = hash('sha512', $salt . $password, true);
|
|
do
|
|
{
|
|
$hash = hash('sha512', $hash . $password, true);
|
|
} while (--$count);
|
|
$hash = self::drupal_base64($hash, strlen($hash), $itoa64);
|
|
return substr('$S$' . $itoa64[$iterations] . $salt . $hash, 0, 55);
|
|
}
|
|
|
|
// Drupal's own Base64 implementation.
|
|
|
|
protected static function drupal_base64($input, $count, $chars)
|
|
{
|
|
$output = '';
|
|
$i = 0;
|
|
do
|
|
{
|
|
$value = ord($input[$i++]);
|
|
$output .= $chars[$value & 0x3f];
|
|
if ($i < $count) $value |= ord($input[$i]) << 8;
|
|
$output .= $chars[($value >> 6) & 0x3f];
|
|
if ($i++ >= $count) break;
|
|
if ($i < $count) $value |= ord($input[$i]) << 16;
|
|
$output .= $chars[($value >> 12) & 0x3f];
|
|
if ($i++ >= $count) break;
|
|
$output .= $chars[($value >> 18) & 0x3f];
|
|
} while ($i < $count);
|
|
return $output;
|
|
}
|
|
|
|
// Joomla's MD5-based password hashing algorithm.
|
|
|
|
public static function joomla($password, $salt = null)
|
|
{
|
|
if ($salt !== null && strlen($salt) > 33)
|
|
{
|
|
$salt = substr($salt, 33);
|
|
}
|
|
else
|
|
{
|
|
$salt = Rhymix\Framework\Security::getRandom(32, 'hex');
|
|
}
|
|
return md5($password . $salt) . ':' . $salt;
|
|
}
|
|
|
|
// KimsQ Rb's algorithms.
|
|
|
|
public static function kimsqrb($password, $salt = null)
|
|
{
|
|
if (preg_match('/(\$[1-4])\$([0-9]{14})$/', $salt, $matches))
|
|
{
|
|
$date = '$' . $matches[2];
|
|
$fakesalt = substr(base64_encode(substr($date, 1) . 'salt'), 0, 22);
|
|
switch ($matches[1])
|
|
{
|
|
case '$1': return self::password_hash($password, 1, ['cost' =>10, 'salt' => $fakesalt]) . '$1' . $date;
|
|
case '$2': return hash('sha512', $password . $fakesalt) . '$2' . $date;
|
|
case '$3': return hash('sha256', $password . $fakesalt) . '$3' . $date;
|
|
case '$4': return md5(sha1(md5($password . $fakesalt))) . '$4' . $date;
|
|
}
|
|
}
|
|
|
|
$date = '$' . date('YmdHis');
|
|
$fakesalt = substr(base64_encode(substr($date, 1) . 'salt'), 0, 22);
|
|
return self::password_hash($password, 1, ['cost' =>10, 'salt' => $fakesalt]) . '$1' . $date;
|
|
}
|
|
|
|
// Bcrypt wrapper for PHP 5.4.
|
|
|
|
public static function password_hash($password, $algo = 1, $options = [])
|
|
{
|
|
if (!isset($options['salt']) || !preg_match('/^[0-9a-zA-Z\.\/]{22,}$/', $options['salt']))
|
|
{
|
|
$options['salt'] = Rhymix\Framework\Security::getRandom(22, 'alnum');
|
|
}
|
|
if (!isset($options['cost']) || $options['cost'] < 4 || $options['cost'] > 31)
|
|
{
|
|
$options['cost'] = 10;
|
|
}
|
|
|
|
$salt = '$2y$' . sprintf('%02d', $options['cost']) . '$' . $options['salt'];
|
|
return @crypt($password, $salt);
|
|
}
|
|
}
|