rumos » 10.03.2010 1:17
привет всем.
прошу простить мою наглость, поиском не пользовался (на вашем сайте), но вдруг кто подскажет.
вводная:
есть дамп от phpBB версии 3.10. (кодировка UTF-8)
есть CMS. она написана на с++ поэтому подключить, наверное очень удобный, плагин для авторизации нет возможности (IPC не подходит по ряду причин).
нужно организовать возможность авторизации внутри системы по логинам и паролям от пользователей phpBB (нужна только авторизация, т.е. функция, которая вернёт номер строки юзера(авторизация верна) или 0(и пофиг почему) )
вопрос:
смотрю я в таблицу phpbb_users.. и вижу что пароль имеет длину 40 байт (по крайней мере поле), и не md5 это даже и близко (не по длине не на вид ).
не обладает ли кто информацией, что есть это поле в реальности, и каким методом прекрасные 32 байта превращаются в 40 (если СП5 не участвует, то опишите кто-нибудь алгоритм в терминах пароль, хешируем/шифруем с ключом который берём оттуда-то и т.д.) ?
спасибо.
ушёл копать исходники..
Добавлено спустя 2 часа 5 минут 18 секунд:
1. длина хеша пароля - 34 байта.
2. первые 3 байта - сигналка.
3. _hash_crypt_private - используется в проверке авторизации и в phpbb_hash. в первом и во втором случае - одинаковые аргументы первый (оригинальный пароль) и последний (алфавит под base64). вывод- второй параметр (в первом случае результат какой-то функции из случайной сигнатуры преобразованной по base64 видимо, не разбирал её; во-втором случае - уже имеющийся хеш ) либо не имеет значения, либо оба раза содержит ключевую информацию. 3.1. - не верю. 3.2. -допустим, временный вывод - преобразованный пароль содержит ту случайную подпись.
4. анализируем _hash_crypt_private
$output = '*';
//дефолтный результат
if (substr($setting, 0, 3) != '$H$')
{
return $output;
}
// 4.1. 2 - верно.
$count_log2 = strpos($itoa64, $setting[3]);
// 4.2. 4-ый байт что-то содержит
if ($count_log2 < 7 || $count_log2 > 30)
{
return $output;
}
//4.3. загадочно.. впрочем нас устраивает, это равно '9' (как символ, видимо и AsIs тоже )
$count = 1 << $count_log2;
//4.4. двигаем 1-цу влево 9 раз, получаем 2**9 == 512. ок.
$salt = substr($setting, 4, 8);
//4.5. salt == "AyacHVuG". например.
if (strlen($salt) != 8)
{
return $output;
}
//4.6. милая глупость. почему бы не проверить ещё раньше(в районе проверки сигналки ), что длина setting==34.
//пространные рассуждения об использовании built-in md5 и извинения за последующие строчки.
$hash = md5($salt . $password, true);
do
{
$hash = md5($hash . $password, true);
}
while (--$count);
//4.7. либо $hash=pack('H*', $hash) если пхп старый.
//как я понимаю делается MD5 512 раз ? ..убить бы за такое.. не такой уж md5 и примитив..
$output = substr($setting, 0, 12);
//4.8 подбираем сигналку и сальт
$output .= _hash_encode64($hash, 16, $itoa64);
//4.9 блин :) ...(спустя некоторое время - резюмируя - перевод метода _hash_encode64 и создание аналога 4 привело к желаемому результату )
Добавлено спустя 3 минуты 36 секунд:
к чему это всё.. лучше бы водки выпили.
Добавлено спустя 3 минуты 19 секунд:
последний з.ы. md5 в php5+ при задании аргумента true выдаёт rawdata, при php5- - возможность по умолчанию отсутствует, потому и танцы с pack.