‏نمایش پست‌ها با برچسب Security Programming. نمایش همه پست‌ها
‏نمایش پست‌ها با برچسب Security Programming. نمایش همه پست‌ها

Hashing و Encryption




Hashing و Encryption هردو روشهایی برای رمزنگاری هستند، نکته قابل توجه این است که هنگامی که متنی را Hash می‌کنید دیگر روش ساده‌ای تحت عنوان dehash کردن آن وجود ندارد و شما برای اینکه متنی را با آن مقایسه بکنید مجبورید آن متن را با همان شیوه Hash کنید و سپس با متن hash شده مقایسه نمایید، در صورتی که یک متن Encrypt شده را می‌توانید Decrypt کرده و با یک متن دیگر مقایسه کنید.

احتمالا می‌دانید که روشهای Encryption مختلفی وجود دارند، در اینجا من کدی را که سالها پیش با استفاده از الگوریتم SHA و با VB.NET نوشته بودم در اختیارتان می‌گذارم:

Imports System.Security.Cryptography
Imports System.Text
.
.
.
 Public Function GetEncryptedData(ByVal Data As String) As String

        Dim shaM As New SHA1Managed
        Convert.ToBase64String(shaM.ComputeHash(Encoding.ASCII.GetBytes(Data)))
        Dim eNC_data() As Byte = ASCIIEncoding.ASCII.GetBytes(Data)
        Dim eNC_str As String = Convert.ToBase64String(eNC_data)

        Return eNC_str

    End Function

    Public Function GetDecryptedData(ByVal Data As String) As String

        Dim dEC_data() As Byte = Convert.FromBase64String(Data)
        Dim dEC_Str As String = ASCIIEncoding.ASCII.GetString(dEC_data)
        Return dEC_Str

    End Function

همانطور که ملاحظه کردید دو تابع به منظور Encrypt مردن و Decrypt کردن در کد فوق نوشته شده‌است.

در مورد Hashing که معمولا برای نگهداری passeord ها استفاده می‌شود یکی از روشها استفاده از System.Web.Security است:

System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(txtPwd.Text, "MD5").ToString()

همانطور که ملاحظه کردید من از MD5 به عنوانت فرمت Hashing استفاده کردم

کار با Directory Services



اضافه کردن و یا حذف کردن یک User در یک Domain
اضافه کردن و یا حذف کردن یک Group در یک Domain
اضافه کردن و یا حذف کردن یک User در یک Group
اینها کارهای مدیریتی هستند که یک Network Administrator معمولا انجام می‌دهد، ولی اگر قرار باشد که این کارها از طریق نرم‌افزار شما انجام شود چه؟
در لینک زیر نمونه کدهایی که من سالها پیش به این منظور نوشته‌ام را پیدا می‌کنید، البته ممکن است که روش اجرای این کد کمی قدیمی شده باشد، این کد برای .NET Framework 1.1 و با VB.NET نوشته شده است.

نکاتی در باره Login page


شما هنگامی به صفحه Login نیاز دارید که اطلاعات کاربرانتان را به خصوص ID و Password آنها را در یک پایگاه داده ها ذخیره کرده باشید، این پایگاه داده ها می تواند  از انواع ساده مانند XML و یا انواع پیچیده RDBMS مانند SQL Database باشد.

در هر صورت به یاد داشته باشید که نگهداری از کلمات عبور بدون Encryption و یا Hash کردن به هیچ وجه قابل قبول نیست، من Hash را ترجیح می دهم چون در این مورد چیزی تحت عنوان DeHash وجود ندارد، شما می توانید در صفحه Registration که قرار است بواسطه آن یک رکورد برای هر کاربر جدید ثبت کنید، کلمات عبور را ابتدا Hash نموده و سپس ذخیره نمایید.

نکات Configuration

احتمالا می دانید که سه شیوه Authentication در .NET Framework پشتیبانی می شود، Windows، Forms و Passport، Windows Authentication هنگامی قابل استفاده خواهد بود که وظیفه  Authenticateکردن را به عهده Domain Controller بگذارید، در این صورت نیازی به Login page هم نخواهید داشت، Passport وقتی مناسب خواهد بود که سایتهای یکپارچه ای داشته باشید که Authentication مشترک داشته باشند مانند سایتهای مختلف Google که در همه آنها با یک نام کاربری و کلمه عبور شناخته می شوید، گزینه مناسب برای مثال ما Forms است.

کد XML مربوط به Forms Authentication در Web.config
<authentication mode="Forms">
                  <forms loginUrl="LoginPage.aspx" protection="All">
                  forms>
authentication>

کد فوق هر درخواست برای هر صفحه ای را فقط به شرطی پاسخ می دهد که درخواست دهنده قبلا در صفحه LoginPage.aspx عملیات login را انجام داده باشد در غیر این صورت او را به این صفحه هدایت کرده و پس از انجام Login مجددا صفحه درخواست شده را Load می کند.

در مورد Authorization نیز توجه داشته باشید که دسترسی کاربران Anonymous را محدود کنید:

<authorization>
      <deny users="?"/>
authorization>

Identity tag را هم فراموش نکنید، در این حالت حتی اگر IIS دسترسی Ananymous را مجاز بداند، Web.config آنرا Override می کند.





<identity impersonate="true"/>


تابعی که من برای انجام Validation در صفحه Login نوشته ام، البته پیشنهاد می کنم که Connection String را Hash کنید.

Boolean Validateit(string uid, string pwd)
{
System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection("Data Source=.;Initial Catalog=Training;Persist Security Info=True;User ID=guser;Password=123");
            System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("select id, fname, lname, uname, pwd from users", cn);
            cn.Open();
            System.Data.SqlClient.SqlDataReader dr = cmd.ExecuteReader();
            while (dr.Read())
            {
                if (txtUid.Text == dr.GetValue(3).ToString())
                {

                    if (System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(txtPwd.Text, "MD5").ToString() == dr.GetValue(4).ToString())
                    {
                        fullname = dr.GetValue(1).ToString() + " " + dr.GetValue(2).ToString();
                        return true;
                    }
                }
            }
            cn.Close();
            return false;
}
استفاده از این تابع در Click event یک Button

protected void btnLgn_Click(object sender, EventArgs e)
        {
            if (Validateit(txtUid.Text, txtPwd.Text) == true)
            {
                System.Web.Security.FormsAuthentication.RedirectFromLoginPage(fullname, false);
                Session["username"]=fullname;
            }
        }

در ضمن، fullname یک متغیر رشته ای است که در Class Scope تعریف شده است.






به نظر من بهتر است برای صفحاتی مانند Login امکان Cache غیر فعال گردد، یک روش ساده استفاده از شیئ Response در Page load event است:
Response.CacheControl = "no-cache";

نکته آخر اینکه می‌توانید از Component های حاضر و آماده FrameWork هم استفاده کنید، مثل LoginControl و غیره، در هر صورت مفاهیم اجرا تغییری نخواهد کرد فقط به کد نویسی کمتری نیاز خواهید داشت ولی فراموش نکنید که کار سخت شما هنگام پیاده‌سازی منجر به یک Maintenance راحت خواهد شد البته به شرط اینکه زحمت موثری کشیده شده باشد.