المشاركات : 7,394
المواضيع 803
الإنتساب : Sep 2013
السمعة :
847
الشكر: 13249
تم شكره 18797 مرات في 4415 مشاركات
اشكر مقدما كل من يساعدني على هذا السؤال
اريد تحويل الكود التالي الى كود vb.net
كود :
/**
* Generates a random salt
*
* @return string The salt.
*/
function generate_salt()
{
return random_str(8);
}
/**
* Salts a password based on a supplied salt.
*
* @param string The md5()'ed password.
* @param string The salt.
* @return string The password hash.
*/
function salt_password($password, $salt)
{
return md5(md5($salt).$password);
}
$pass = $mybb->input['password'];
$md5pass = md5($pass);
$salt = generate_salt();
$salted_pass = salt_password($md5pass, $salt);
المشاركات : 403
المواضيع 2
الإنتساب : Feb 2014
السمعة :
65
الشكر: 32
تم شكره 835 مرات في 278 مشاركات
.....
منقول مع تعديل بسيط ليناسب طلبك
ملاحظات:
1- يجب حفظ كل من قيمتي salt وsalted_password في قاعدة البيانات في جدول المستخدم (قد يقوم البعض بحفظ salt في
مكان آخر مع الإشارة إلى رقم العضو لزيادة صعوب التتبع).
2-ولمعرفة التطابق (كتسجيل الدخول مثلا) ترسل password المدخلة مع قيمة salt المحفوظة في قاعدة البيانات إلى الدالة salt_password
ومن ثم تطابق القيمة المعادة من الدالة salt_password مع قيمة salted_password المحفوظة في قاعدة البيانات.
3- المفروض أن تكون طريقة salting password غير معروفة بشكل سهل من أجل عدم محاولة فكها.
كود :
' ضع 3 أدوات TextBox
' TextBox1 : Password
' TextBox2: Salt
' TextBox3: Salted password
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim md5pass As String = MD5(Me.TextBox1.Text)
Dim salt As String = generate_salt()
Dim salted_password As String = salt_password(md5pass, salt)
Me.TextBox2.Text = salt
Me.TextBox3.Text = salted_password
End Sub
Private Function salt_password(ByVal password As String, ByVal salt As String) As String
Return MD5(MD5(salt) & password)
End Function
Private Function generate_salt() As String
Return random_str(8)
End Function
Private Function random_str(Optional ByVal size = 8) As String
Dim salt As String = String.Empty
Dim characterList As String = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqWrRsStTuUvVwWxXyYzZ123456789"
Dim rnd As New Random
For i = 0 To size - 1
salt &= characterList(rnd.Next(0, (Len(characterList) - 1)))
Next
Return salt
End Function
Public Function MD5(ByVal txt As String) As String
Dim result As String = String.Empty
Dim objMd5 As New System.Security.Cryptography.MD5CryptoServiceProvider()
Dim byts() As Byte = System.Text.Encoding.UTF8.GetBytes(txt)
byts = objMd5.ComputeHash(byts)
For Each b As Byte In byts
result &= b.ToString("x2")
Next
Return result
End Function
لتجربة صحة كلمة المرور إضغط على Button1 ثم اترك بيانات TextBox2 وTextBox3 التي تحتوي على salt وsalted_password كما هي
وحاول تغيير كلمة المرور في TextBox1 والذي يحتوي password ثم اضغط Button2 الموجود في الكود التالي:
كود :
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim md5pass As String = MD5(Me.TextBox1.Text)
Dim salt As String = Me.TextBox2.Text
Dim salted_password As String = salt_password(md5pass, salt)
If salted_password = Me.TextBox3.Text Then
MsgBox("كلمة المرور صحيحة")
Else
MsgBox("عفواً... كلمة المرور غير صحيحة")
End If
End Sub
.....
المشاركات : 7,394
المواضيع 803
الإنتساب : Sep 2013
السمعة :
847
الشكر: 13249
تم شكره 18797 مرات في 4415 مشاركات
بارك الله فيك اخي الكريم
انا اعاني من ستايل المنتدى الحالي
وكل مااختار الاستايل الاول الاقي نفسي بالستايل هذا.
صراحة مزعج الخطوط مش واضحة , وصغيرة.
_____________________
بالنسبة للفكرة اريد تحويل كود مشفر بواسطة منتدى vbulletin الى تشفير منتدى mybb ولي نقاش طويل هنا
وجدت عدة دوال متداخلة وبصراحة الدعم ماقصر معي بس انا اللي فهمي صعب
شكر الله لك اخي vbnet
المشاركات : 7,394
المواضيع 803
الإنتساب : Sep 2013
السمعة :
847
الشكر: 13249
تم شكره 18797 مرات في 4415 مشاركات
الكود رهيب اخي الكريم
لكن انا احاول اصيغ كود مناسب لدوال منتدى mybb وهي التالي:
كود :
function generate_salt()
{
return random_str(8);
}
function salt_password($password, $salt)
{
return md5(md5($salt).$password);
}
$pass = $mybb->input['password'];
$md5pass = md5($pass);
$salt = generate_salt();
$salted_pass = salt_password($md5pass, $salt);
function generate_loginkey()
{
return random_str(50);
}
function random_str($length="8")
{
$set = array("a","A","b","B","c","C","d","D","e","E","f","F","g","G","h","H","i","I","j","J","k","K","l","L","m","M","n","N","o","O","p","P","q","Q","r","R","s","S","t","T","u","U","v","V","w","W","x","X","y","Y","z","Z","1","2","3","4","5","6","7","8","9");
$str = '';
for($i = 1; $i <= $length; ++$i)
{
$ch = my_rand(0, count($set)-1);
$str .= $set[$ch];
}
return $str;
}
/**
* Wrapper function for mt_rand. Automatically seeds using a secure seed once.
*
* @param int Optional lowest value to be returned (default: 0)
* @param int Optional highest value to be returned (default: mt_getrandmax())
* @param boolean True forces it to reseed the RNG first
* @return int An integer equivalent of a secure hexadecimal seed
*/
function my_rand($min=null, $max=null, $force_seed=false)
{
static $seeded = false;
static $obfuscator = 0;
if($seeded == false || $force_seed == true)
{
mt_srand(secure_seed_rng());
$seeded = true;
$obfuscator = abs((int) secure_seed_rng());
// Ensure that $obfuscator is <= mt_getrandmax() for 64 bit systems.
if($obfuscator > mt_getrandmax())
{
$obfuscator -= mt_getrandmax();
}
}
if($min !== null && $max !== null)
{
$distance = $max - $min;
if($distance > 0)
{
return $min + (int)((float)($distance + 1) * (float)(mt_rand() ^ $obfuscator) / (mt_getrandmax() + 1));
}
else
{
return mt_rand($min, $max);
}
}
else
{
$val = mt_rand() ^ $obfuscator;
return $val;
}
}
الدالتين my_rand and mt_rand
وغيرها هل يمكن برمجة مثلها
المشاركات : 7,394
المواضيع 803
الإنتساب : Sep 2013
السمعة :
847
الشكر: 13249
تم شكره 18797 مرات في 4415 مشاركات
اظنك جبت الحل كله ماشاء الله
بس ودي اتاكد من شغله هل الكود المشفر ينجح مع Mybb؟
لان كل الاكواد حصلتها بمشاركتك لكن الدالة my_rand و mt_rand هل نقدر نقول استغنينا عنها بالكود اللي كتبت؟
المشاركات : 403
المواضيع 2
الإنتساب : Feb 2014
السمعة :
65
الشكر: 32
تم شكره 835 مرات في 278 مشاركات
.....
عدلت الكود السابق لأنني دمجت كل من الدالتين generate_salt وrandom_str ولكن أرجعتهما منفصلتين لتتطابق مع الكود،
خصوصاً بعد ما وجدت أن الدالة generate_loginkey استخدمت الدالة random_str بشكل آخر في الكود الثاني منك.
"بس ودي اتاكد من شغله هل الكود المشفر ينجح مع Mybb؟"
لا أعلم طريقة برمجة MyBB ولكن كل مبرمج أو فريق عمل لهم أسلوبهم.
mt_rand وظيفتها تعطيك رقم عشوائي من نوع Integer بطريقتين:
1: رقم عشوائي مفتوح.
2: رقم عشوائي محصور بين رقمين.
وهي موجود في VB.NET كالتالي:
كود :
Private Function mt_rand(Optional ByVal min As Integer = 0, Optional ByVal max As Integer = 0) As Integer
Dim rnd As New Random
If max = 0 Then
Return rnd.Next
Else
Return rnd.Next(min, max)
End If
End Function
الخلاصة يمكن التحويل من PHP إلى VB.NET والعكس من شخص متمكن من اللغتين
وللعلم هيكلية PHP قريبة من هيكلية #C
.....
المشاركات : 7,394
المواضيع 803
الإنتساب : Sep 2013
السمعة :
847
الشكر: 13249
تم شكره 18797 مرات في 4415 مشاركات
نعم طريقتك مذهلة نجح انشاء كلمة مرور وسالت صالحة ل mybb التغيير فقط وضع smal letter بعدها capital letter
aAbBcCdD
-------------
بالنسبة لتوليد كلمة مرور لنوع vbulletin وجود كود يعمل ضمن جملة التنفيذ sql
كود :
UPDATE user set password = MD5(concat(MD5('new password'), user.salt)) WHERE userid=29
كود :
MD5(concat(MD5('new password'), user.salt))
الجملة التالية هل يمكن استخدامها بطريقة اخرى يعني هل نقدر توليد md5 مثل الموجود بالكود اللي اضفته؟
المشاركات : 7,394
المواضيع 803
الإنتساب : Sep 2013
السمعة :
847
الشكر: 13249
تم شكره 18797 مرات في 4415 مشاركات
اتعبتك معي كثيرا فالله يعينك ويعوضك بخير مما ذهب منك من وقت وجهد
كود :
function import()
{
global $import_session;
// Get members
$query = $this->old_db->simple_select("user", "*", "", array('order_by' => 'userid', 'order_dir' => 'asc', 'limit_start' => $this->trackers['start_users'], 'limit' => $import_session['users_per_screen']));
while($user = $this->old_db->fetch_array($query))
{
$this->insert($user);
}
}
function convert_data($data)
{
$insert_data = array();
// vBulletin 4 values
$insert_data['usergroup'] = $this->board->get_group_id($data['usergroupid'], array("not_multiple" => true));
$insert_data['additionalgroups'] = str_replace($insert_data['usergroup'], '', $this->board->get_group_id($data['usergroupid']));
$insert_data['displaygroup'] = $this->board->get_group_id($data['usergroupid'], array("not_multiple" => true));
$insert_data['import_usergroup'] = $this->board->get_group_id($data['usergroupid'], array("original" => true));
$insert_data['import_additionalgroups'] = $this->board->get_group_id($data['usergroupid'], array("original" => true));
$insert_data['import_displaygroup'] = $data['displaygroupid'];
$insert_data['import_uid'] = $data['userid'];
$insert_data['username'] = encode_to_utf8($data['username'], "user", "users");
$insert_data['email'] = $data['email'];
$insert_data['regdate'] = $data['joindate'];
$insert_data['lastactive'] = $data['lastactivity'];
$insert_data['lastvisit'] = $data['lastvisit'];
$insert_data['website'] = $data['homepage'];
$avatar = $this->get_avatar($data['avatarid']);
if(!$avatar)
{
$customavatar = $this->get_custom_avatar($data['userid']);
if(!$customavatar)
{
$insert_data['avatardimensions'] = '';
$insert_data['avatar'] = '';
$insert_data['avatartype'] = '';
}
}
else
{
list($width, $height) = @getimagesize($avatar['avatarpath']);
$insert_data['avatardimensions'] = $width.'|'.$height;
$insert_data['avatar'] = $avatar['avatarpath'];
$insert_data['avatartype'] = 'remote';
}
$insert_data['lastpost'] = $data['lastpost'];
$data['birthday'] = trim($data['birthday']);
if(!empty($data['birthday']))
{
list($bmonth, $bday, $byear) = explode("-", $data['birthday']);
$insert_data['birthday'] = $bday."-".$bmonth."-".$byear;
}
// Don't ask me why some guys insert an ICQ number with more than 9 characters, but we need to avoid sql errors...
$insert_data['icq'] = substr($data['icq'], 0, 10);
$insert_data['aim'] = $data['aim'];
$insert_data['yahoo'] = $data['yahoo'];
$insert_data['skype'] = $data['skype'];
$insert_data['timezone'] = str_replace(array('.0', '.00'), array('', ''), $insert_data['timezone']);
$insert_data['style'] = 0;
$insert_data['referrer'] = $data['referrerid'];
$insert_data['regip'] = my_inet_pton($data['ipaddress']);
$insert_data['totalpms'] = $data['pmtotal'];
$insert_data['unreadpms'] = $data['pmunread'];
$insert_data['passwordconvert'] = $data['password'];
$insert_data['passwordconverttype'] = 'vb4';
$insert_data['passwordconvertsalt'] = $data['salt'];
$insert_data['signature'] = encode_to_utf8($this->bbcode_parser->convert($this->get_signature($data['userid'])), "user", "users");
return $insert_data;
}
----------------------------------
function loginconvert_convert(&$login)
{
global $mybb, $valid_login_types, $db, $settings;
$options = array(
"fields" => array('username', "password", "salt", 'loginkey', 'coppauser', 'usergroup', "passwordconvert", "passwordconverttype", "passwordconvertsalt"),
"username_method" => (int)$settings['username_method']
);
if($login->username_method !== null)
{
$options['username_method'] = (int)$login->username_method;
}
$user = get_user_by_username($login->data['username'], $options);
// There's nothing to check for, let MyBB do everything
// This fails also when no user was found above, so no need for an extra check
if(!isset($user['passwordconvert']) || $user['passwordconvert'] == '')
{
return;
}
if(!array_key_exists($user['passwordconverttype'], $valid_login_types))
{
// TODO: Is there an easy way to make the error translatable without adding a new language file?
redirect($mybb->settings['bburl']."/member.php?action=lostpw", "We're sorry but we couldn't convert your old password. Please select a new one", "", true);
}
else
{
$function = "check_".$valid_login_types[$user['passwordconverttype']];
$check = $function($login->data['password'], $user);
if(!$check)
{
// Yeah, that function is called later too, but we need to know whether the captcha is right
// If we wouldn't call that function the error would always be shown
$login->verify_attempts($mybb->settings['captchaimage']);
$login->invalid_combination(true);
}
else
{
// The password was correct, so use MyBB's method the next time (even if the captcha was wrong we can update the password)
$salt = generate_salt();
$update = array(
"salt" => $salt,
"password" => salt_password(md5($login->data['password']), $salt),
"loginkey" => generate_loginkey(),
"passwordconverttype" => "",
"passwordconvert" => "",
"passwordconvertsalt" => "",
);
$db->update_query("users", $update, "uid='{$user['uid']}'");
// Make sure the password isn't tested again
unset($login->data['password']);
// Also make sure all data is available when creating the session (otherwise SQL errors -.-)
$login->login_data = array_merge($user, $update);
}
}
}
// Password functions
function check_vb($password, $user)
{
if(md5(md5($password).$user['passwordconvertsalt']) == $user['passwordconvert'] || md5($password.$user['passwordconvertsalt']) == $user['passwordconvert'])
{
return true;
}
return false;
}
هذي دالة تحويل تشفير vbulletin to mybb
لي يوم كامل احاول افهمها وما قدرت.
المشاركات : 403
المواضيع 2
الإنتساب : Feb 2014
السمعة :
65
الشكر: 32
تم شكره 835 مرات في 278 مشاركات
.....
"التغيير فقط وضع smal letter بعدها capital letter
aAbBcCdD"
لاحظ أنهم لم يضيفوا الصفر (تم تعديل كود VB.NET بناء عليه).
بالنسبة للجزء:
كود :
UPDATE user set password = MD5(concat(MD5('new password'), user.salt)) WHERE userid=29
فهو يطبق التشفير MD5 داخل قاعدة البيانات MySql وبنفس أسلوب كود PHP الأول ولكن داخل قاعدة البيانات.
يتضمن محرك قواعد بيانات MySql بخدمات كثيرة منها التشفير بـ MD5 داخل جمل الاستعلام.
و CONCAT في MySql تقوم بوصل النصوص مع بعضها ليكونوا نصاً واحداً مثل '123' و '456' سيصبحان '123456'.
كود :
SELECT CONCAT('123','456')
النتيجة
'123456'
أيضاً
SELECT CONCAT('123','456','789')
النتيجة
'123456789'
أما الدوال الأخيرة في الكود الأخير:
import
convert_data
loginconvert_convert
check_vb
تبدو لي معقدة وتحتاج لوقت طويل، وقد لا أصل لنتائج مرضية، خصوصاً أنني لست خبيراً في برمجة VB.NET فضلاً عن PHP.
.....
المشاركات : 7,394
المواضيع 803
الإنتساب : Sep 2013
السمعة :
847
الشكر: 13249
تم شكره 18797 مرات في 4415 مشاركات
ماشاء الله تبارك الله
المعلومات اللي قدمتها لي رائعة جدا .
وقدرة Mysql على التشفير شيء جديد بالنسبة لي.
|