Доброй ночи, господа и дамы!
Я думаю, все помнят, как в свое время были популярны форумы и, конечно же, были популярны форумы на phpBB. Сегодня они, к моему некоторому сожалению, уступают место соц. сетям, но еще не до конца отошли в мир иной.
Мой сегодняшний пост будет о том, как я интегрировал phpBB с приложением на C# в части аутентификации пользователей. Не думаю, что многим он будет интересен, но, как мне кажется, найдутся люди…
Для начала, откроем файл includes\functions.php и найдем функции phpbb_check_hash, _hash_crypt_private и _hash_encode64. Именно их нам и предстоит портировать на C# и именно они аутентифицирует пользователей в phpBB.
Подключим следующие библиотеки:
using System.Security.Cryptography; using System.Text;
И начнем аккуратно переводить функции на другой язык. Я заведомо не менял названия функций и переменных в соответствие с принятым в C# форматом, а оставил их такими, как и в phpBB.
public bool phpbb_check_hash(string password, string hash) { var itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; if (hash.Length == 34) { return (_hash_crypt_private(password, hash, itoa64) == hash) ? true : false; } return (Md5(Encoding.UTF8.GetBytes(password)) == Encoding.UTF8.GetBytes(hash)) ? true : false; }
public string _hash_crypt_private(string password, string setting, string itoa64) { var output = "*"; if (setting.Substring(0, 3) != "$H$" && setting.Substring(0, 3) != "$P$") { return output; } var countLog2 = itoa64.IndexOf(setting[3]); if (countLog2 < 7 || countLog2 > 30) { return output; } var count = 1 << countLog2; var salt = setting.Substring(4, 8); if (salt.Length != 8) { return output; } var str = new byte[Encoding.UTF8.GetBytes(salt).Length + Encoding.UTF8.GetBytes(password).Length]; Array.Copy(Encoding.UTF8.GetBytes(salt), 0, str, 0, Encoding.UTF8.GetBytes(salt).Length); Array.Copy(Encoding.UTF8.GetBytes(password), 0, str, Encoding.UTF8.GetBytes(salt).Length, Encoding.UTF8.GetBytes(password).Length); var hash = Md5(str); do { str = new byte[hash.Length + Encoding.UTF8.GetBytes(password).Length]; Array.Copy(hash, 0, str, 0, hash.Length); Array.Copy(Encoding.UTF8.GetBytes(password), 0, str, hash.Length, Encoding.UTF8.GetBytes(password).Length); hash = Md5(str); } while (--count != 0); output = setting.Substring(0, 12); output += _hash_encode64(hash, 16, itoa64); return output; }
public string _hash_encode64(byte[] input, int count, string itoa64) { var output = ""; var i = 0; do { int value = input[i++]; output += itoa64[value & 0x3f]; if (i < count) { value |= input[i] << 8; } output += itoa64[(value >> 6) & 0x3f]; if (i++ >= count) { break; } if (i < count) { value |= input[i] << 16; } output += itoa64[(value >> 12) & 0x3f]; if (i++ >= count) { break; } output += itoa64[(value >> 18) & 0x3f]; } while (i < count); return output; }
public byte[] Md5(byte[] str) { var md5CryptoServiceProvider = new MD5CryptoServiceProvider(); return md5CryptoServiceProvider.ComputeHash(str); }
Я не знаю, пригодится ли этот код кому-то, но в свое время я перерыл очень много форумов, но так и ничего не нашел на эту тему. Именно поэтому я и решил поделиться кодом с общественностью.
Заранее спасибо за Ваши комментарии!
ссылка на оригинал статьи http://habrahabr.ru/post/189240/
Добавить комментарий