raha1234567
دوشنبه 18 مرداد 1389, 01:29 صبح
Hash کردن به معنای تولید کدی منحصربه فرد و یکتا و غیرقابل بازگشت برای یک رشته است )بدین معنا که نمی توان فهمید کد تولید شده نتیجه چه رشته ای است) از این رو داده های مهم در جداول پایگاه داده یا هرجای دیگر باید Hash شوند تا در صورت نفوذ هکرها به پایگاه داده نتوانند به محتوای ان داده پی ببرند.
یکی از این داده های مهم که حتما باید Hash شود Password کاربران است .
برای Hash کردن داده در .Net الگوریتمی با نام MD5 برای این کار در نظر گرفته شده است .
الگوریتم MD5 به تولید بایتهایی از رشته داده شده می پردازد در این مقاله سعی خواهم کرد به چگونگی استفاده از این الگوریتم بپردازم.
فرض من این است که پایگاه داده ای در SQL Server با نام Test1 و جدولی به نام users که دارای دو فیلد username و userpassword است داریم برای ساخت جدول از دستور زیر استفاده کنید.
create table users(username varchar(50) primary key,userpassword varbinary(50))
همانگونه که می بینید فیلدی را که می خواهید کد Hash در آن ذخیره شود باید از نوع varbinary باشد.
همچنین فرمی با دو کنترل Textbox به نامهای txtusername و txtpassword به همراه یک کنترل button داریم در این فرم کاربر می تواند username و password خود را وارد کند و برنامه آنرا در جدول users ذخیره می کند البته پسورد کاربر hash می شود.
برای استفاده از الگوریتم های Hashing در ابتدا فضای نام System.Security.Cryptography را به برنامه اضافه کنید.
حال ما تابعی به نام Hash را می نویسیم ،کار این تابع گرفتن یک رشته و دادن یک مقدار Hash است. این مقدار آرایه ای از بایتها است.
VB.NET
Private Function hash(ByVal str As String) As Byte()
Dim crypt As New MD5CryptoServiceProvider()
Dim bytes() As Byte
bytes = System.Text.ASCIIEncoding.ASCII.GetBytes(str)
Return crypt.ComputeHash(bytes)
End Function
C#.NET
private Byte[] hash(string str)
{
MD5CryptoServiceProvider crypt=new MD5CryptoServiceProvider();
Byte[] bytes;
bytes=System.Text.ASCIIEncoding.ASCII.GetBytes(str );
return crypt.ComputeHash(bytes);
}
حال به مثال خود برمی گردیم .
در ابتدا متغیرهای زیر را به صورت سراسری تعریف کنید:
VB.NET
Private con As SqlConnection
Private com As SqlCommand
C#.NET
private SqlConnection con;
private SqlCommand com;
در رویداد Load فرم دستورات زیر را بنویسید
VB.NET
con = New SqlConnection
con.ConnectionString = "Data Source=.;Initial Catalog=Test1;Integrated Security=true"
C#.NET
con = new SqlConnection();
con.ConnectionString = "Data Source=.;Initial Catalog=Test1;Integrated Security=True";
در رویداد click کنترل Button دستورات زیر را بنویسید:
VB.NET
Dim hashvalue() As Byte
hashvalue = hash(txtpassword.Text)
con.Open()
com = New SqlCommand
com.Connection = con
com.CommandText = "insert into users values(@username,@userpassword)"
com.Parameters.AddWithValue("@username", txtusername.Text)
com.Parameters.AddWithValue("@userpassword", hashvalue)
com.ExecuteNonQuery()
con.Close()
C#.NET
byte[] hashvalue;
hashvalue = hash(txtpassword.Text);
con.Open();
com = new SqlCommand();
com.Connection = con;
com.CommandText = "insert into users values(@username,@userpassword)";
com.Parameters.AddWithValue("@username", txtusername.Text);
com.Parameters.AddWithValue("@userpassword", hashvalue);
com.ExecuteNonQuery();
con.Close();
حالا برنامه را اجرا کنید . و در فرم username و password هایی را وارد کنید.
اگر به SQL Server رفته و نتیجه دستور زیر را ببینید:
select *from users
می بینید که فیلد passowrd به صورت مجموعه ای از بایتها ذخیره شده است که این مجموعه کاملا unique است.
تا اینجا ما نحوه چگونگی تولید و ذخیره یک رشته hash مانند password را گفتیم از اینجا به بعد به تکمیل مقاله فرم Login در ابتدای برنامه و چگونگی مقایسه دو مقدار hash می پردازیم بهتر است در ابتدا این مقاله را در آدرس زیر بخوانید:
winlin.epage.ir/fa/module.content_Page.25-05.html (http://winlin.epage.ir/fa/module.content_Page.25-05.html)
حالا فرض کنید که در ابتدای پروژه یا برنامه خود فرم Login دارید که کار این فرم گرفتن username و پسورد کاربر و در صورت تائید ، وارد شدن به برنامه است
اما در این باره برنامه باید username و password کاربر را در فرم Login گرفته و password وارد شده را hash کرده و با password ذخیره شده مقایسه کند در صورتی که مساوی بود اجازه ورود بدهد.
اما نکته وجود دارد و آن اینکه برای مقایسه دو مجموعه بایت نمی توان ار علامت = استفاده کرد بلکه باید انها را بایت به بایت خواند و هربایت را به تنهایی مقایسه کرد .
حالا فرم Login خود را بسازید (پیش فرض ما همان فرم Login است که قبلا گفته ایم)
برای مقایسه دو مجموعه از بایت تابعی به نام comparetwobytes نوشتیم آنرا به برنامه خود اضافه کنید:
VB.NET
Private Function comparetwobytes(ByVal tmphash As Byte(), ByVal tmpnewhash As Byte()) As Boolean
Dim bEqual As Boolean = False
If tmpnewhash.Length = tmphash.Length Then
Dim i As Integer
Do While (i < tmpnewhash.Length) AndAlso (tmpnewhash(i) = tmphash(i))
i += 1
Loop
If i = tmpnewhash.Length Then
bEqual = True
End If
End If
Return bEqual
End Function
C#.NET
private Boolean comparetwobytes(Byte[] tmphash, Byte[] tmpnewhash)
{
bool bEqual = false;
if (tmpnewhash.Length == tmphash.Length)
{
int i = 0;
while ((i < tmpnewhash.Length) && (tmpnewhash[i] == tmphash[i]))
{
i += 1;
}
if (i == tmpnewhash.Length)
{
bEqual = true;
}
}
return bEqual;
}
توجه کنید تابع hash نیز باید به قسمت کدنویسی فرم Login نیز اضافه کنید
حالا در رویداد click کنترل Ok دستورات زیر را بنویسید
VB.NET
Dim hashvalue As Byte()
hashvalue = hash(PasswordTextBox.Text)
com = New SqlCommand
con.Open()
com.Connection = con
com.CommandText = "select * from users"
Dim reader As SqlDataReader
reader = com.ExecuteReader
Dim value As Boolean = False
While reader.Read
If UsernameTextBox.Text = reader.GetString(0) And comparetwobytes(reader.GetValue(1), hashvalue) = True Then
value = True
Exit While
End If
End While
If value Then
MessageBox.Show("نام کاربری و رمز ورودی صحیح است")
Else
MessageBox.Show("نام کاربری یا رمز ورودی اشتباه است")
End If
con.Close()
C#.NET
Byte[] hashvalue;
hashvalue = hash(PasswordTextBox.Text);
com=new SqlCommand();
con.Open();
com.Connection = con;
com.CommandText = "select * from users";
SqlDataReader reader = com.ExecuteReader();
Boolean value = false;
while (reader.Read())
{
if ((UsernameTextBox.Text == reader.GetString(0)) && (comparetwobytes((byte[])reader.GetValue(1), hashvalue)))
{
value = true;
break;
}
}
if (value)
MessageBox.Show("نام کاربری و رمز ورودی صحیح است");
else
MessageBox.Show("نام کاربری یا رمز ورودی اشتباه است");
con.Close();
یکی از این داده های مهم که حتما باید Hash شود Password کاربران است .
برای Hash کردن داده در .Net الگوریتمی با نام MD5 برای این کار در نظر گرفته شده است .
الگوریتم MD5 به تولید بایتهایی از رشته داده شده می پردازد در این مقاله سعی خواهم کرد به چگونگی استفاده از این الگوریتم بپردازم.
فرض من این است که پایگاه داده ای در SQL Server با نام Test1 و جدولی به نام users که دارای دو فیلد username و userpassword است داریم برای ساخت جدول از دستور زیر استفاده کنید.
create table users(username varchar(50) primary key,userpassword varbinary(50))
همانگونه که می بینید فیلدی را که می خواهید کد Hash در آن ذخیره شود باید از نوع varbinary باشد.
همچنین فرمی با دو کنترل Textbox به نامهای txtusername و txtpassword به همراه یک کنترل button داریم در این فرم کاربر می تواند username و password خود را وارد کند و برنامه آنرا در جدول users ذخیره می کند البته پسورد کاربر hash می شود.
برای استفاده از الگوریتم های Hashing در ابتدا فضای نام System.Security.Cryptography را به برنامه اضافه کنید.
حال ما تابعی به نام Hash را می نویسیم ،کار این تابع گرفتن یک رشته و دادن یک مقدار Hash است. این مقدار آرایه ای از بایتها است.
VB.NET
Private Function hash(ByVal str As String) As Byte()
Dim crypt As New MD5CryptoServiceProvider()
Dim bytes() As Byte
bytes = System.Text.ASCIIEncoding.ASCII.GetBytes(str)
Return crypt.ComputeHash(bytes)
End Function
C#.NET
private Byte[] hash(string str)
{
MD5CryptoServiceProvider crypt=new MD5CryptoServiceProvider();
Byte[] bytes;
bytes=System.Text.ASCIIEncoding.ASCII.GetBytes(str );
return crypt.ComputeHash(bytes);
}
حال به مثال خود برمی گردیم .
در ابتدا متغیرهای زیر را به صورت سراسری تعریف کنید:
VB.NET
Private con As SqlConnection
Private com As SqlCommand
C#.NET
private SqlConnection con;
private SqlCommand com;
در رویداد Load فرم دستورات زیر را بنویسید
VB.NET
con = New SqlConnection
con.ConnectionString = "Data Source=.;Initial Catalog=Test1;Integrated Security=true"
C#.NET
con = new SqlConnection();
con.ConnectionString = "Data Source=.;Initial Catalog=Test1;Integrated Security=True";
در رویداد click کنترل Button دستورات زیر را بنویسید:
VB.NET
Dim hashvalue() As Byte
hashvalue = hash(txtpassword.Text)
con.Open()
com = New SqlCommand
com.Connection = con
com.CommandText = "insert into users values(@username,@userpassword)"
com.Parameters.AddWithValue("@username", txtusername.Text)
com.Parameters.AddWithValue("@userpassword", hashvalue)
com.ExecuteNonQuery()
con.Close()
C#.NET
byte[] hashvalue;
hashvalue = hash(txtpassword.Text);
con.Open();
com = new SqlCommand();
com.Connection = con;
com.CommandText = "insert into users values(@username,@userpassword)";
com.Parameters.AddWithValue("@username", txtusername.Text);
com.Parameters.AddWithValue("@userpassword", hashvalue);
com.ExecuteNonQuery();
con.Close();
حالا برنامه را اجرا کنید . و در فرم username و password هایی را وارد کنید.
اگر به SQL Server رفته و نتیجه دستور زیر را ببینید:
select *from users
می بینید که فیلد passowrd به صورت مجموعه ای از بایتها ذخیره شده است که این مجموعه کاملا unique است.
تا اینجا ما نحوه چگونگی تولید و ذخیره یک رشته hash مانند password را گفتیم از اینجا به بعد به تکمیل مقاله فرم Login در ابتدای برنامه و چگونگی مقایسه دو مقدار hash می پردازیم بهتر است در ابتدا این مقاله را در آدرس زیر بخوانید:
winlin.epage.ir/fa/module.content_Page.25-05.html (http://winlin.epage.ir/fa/module.content_Page.25-05.html)
حالا فرض کنید که در ابتدای پروژه یا برنامه خود فرم Login دارید که کار این فرم گرفتن username و پسورد کاربر و در صورت تائید ، وارد شدن به برنامه است
اما در این باره برنامه باید username و password کاربر را در فرم Login گرفته و password وارد شده را hash کرده و با password ذخیره شده مقایسه کند در صورتی که مساوی بود اجازه ورود بدهد.
اما نکته وجود دارد و آن اینکه برای مقایسه دو مجموعه بایت نمی توان ار علامت = استفاده کرد بلکه باید انها را بایت به بایت خواند و هربایت را به تنهایی مقایسه کرد .
حالا فرم Login خود را بسازید (پیش فرض ما همان فرم Login است که قبلا گفته ایم)
برای مقایسه دو مجموعه از بایت تابعی به نام comparetwobytes نوشتیم آنرا به برنامه خود اضافه کنید:
VB.NET
Private Function comparetwobytes(ByVal tmphash As Byte(), ByVal tmpnewhash As Byte()) As Boolean
Dim bEqual As Boolean = False
If tmpnewhash.Length = tmphash.Length Then
Dim i As Integer
Do While (i < tmpnewhash.Length) AndAlso (tmpnewhash(i) = tmphash(i))
i += 1
Loop
If i = tmpnewhash.Length Then
bEqual = True
End If
End If
Return bEqual
End Function
C#.NET
private Boolean comparetwobytes(Byte[] tmphash, Byte[] tmpnewhash)
{
bool bEqual = false;
if (tmpnewhash.Length == tmphash.Length)
{
int i = 0;
while ((i < tmpnewhash.Length) && (tmpnewhash[i] == tmphash[i]))
{
i += 1;
}
if (i == tmpnewhash.Length)
{
bEqual = true;
}
}
return bEqual;
}
توجه کنید تابع hash نیز باید به قسمت کدنویسی فرم Login نیز اضافه کنید
حالا در رویداد click کنترل Ok دستورات زیر را بنویسید
VB.NET
Dim hashvalue As Byte()
hashvalue = hash(PasswordTextBox.Text)
com = New SqlCommand
con.Open()
com.Connection = con
com.CommandText = "select * from users"
Dim reader As SqlDataReader
reader = com.ExecuteReader
Dim value As Boolean = False
While reader.Read
If UsernameTextBox.Text = reader.GetString(0) And comparetwobytes(reader.GetValue(1), hashvalue) = True Then
value = True
Exit While
End If
End While
If value Then
MessageBox.Show("نام کاربری و رمز ورودی صحیح است")
Else
MessageBox.Show("نام کاربری یا رمز ورودی اشتباه است")
End If
con.Close()
C#.NET
Byte[] hashvalue;
hashvalue = hash(PasswordTextBox.Text);
com=new SqlCommand();
con.Open();
com.Connection = con;
com.CommandText = "select * from users";
SqlDataReader reader = com.ExecuteReader();
Boolean value = false;
while (reader.Read())
{
if ((UsernameTextBox.Text == reader.GetString(0)) && (comparetwobytes((byte[])reader.GetValue(1), hashvalue)))
{
value = true;
break;
}
}
if (value)
MessageBox.Show("نام کاربری و رمز ورودی صحیح است");
else
MessageBox.Show("نام کاربری یا رمز ورودی اشتباه است");
con.Close();