1.11M Members

Sample C# Windows Form Login Screen

 
10
 

Here is a sample code snippet of logging in a user against a user table in an MSSQL database with password encryption.

Scott Knake

using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;

namespace daniweb
{
  public partial class frmLogin : Form
  {
    /// <summary>
    /// Key for the crypto provider
    /// </summary>
    private static readonly byte[] _key = { 0xA1, 0xF1, 0xA6, 0xBB, 0xA2, 0x5A, 0x37, 0x6F, 0x81, 0x2E, 0x17, 0x41, 0x72, 0x2C, 0x43, 0x27 };
    /// <summary>
    /// Initialization vector for the crypto provider
    /// </summary>
    private static readonly byte[] _initVector = { 0xE1, 0xF1, 0xA6, 0xBB, 0xA9, 0x5B, 0x31, 0x2F, 0x81, 0x2E, 0x17, 0x4C, 0xA2, 0x81, 0x53, 0x61 };

    public frmLogin()
    {
      InitializeComponent();
    }


#if (DEBUG) //Only compile this method for local debugging.
    /// <summary>
    /// Decrypt a string
    /// </summary>
    /// <param name="Value"></param>
    /// <returns></returns>
    private static string Decrypt(string Value)
    {
      SymmetricAlgorithm mCSP;
      ICryptoTransform ct = null;
      MemoryStream ms = null;
      CryptoStream cs = null;
      byte[] byt;
      byte[] _result;

      mCSP = new RijndaelManaged();

      try
      {
        mCSP.Key = _key;
        mCSP.IV = _initVector;
        ct = mCSP.CreateDecryptor(mCSP.Key, mCSP.IV);


        byt = Convert.FromBase64String(Value);

        ms = new MemoryStream();
        cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
        cs.Write(byt, 0, byt.Length);
        cs.FlushFinalBlock();

        cs.Close();
        _result = ms.ToArray();
      }
      catch
      {
        _result = null;
      }
      finally
      {
        if (ct != null)
          ct.Dispose();
        if (ms != null)
          ms.Dispose();
        if (cs != null)
          cs.Dispose();
      }

      return ASCIIEncoding.UTF8.GetString(_result);
    }
#endif

    /// <summary>
    /// Encrypt a string
    /// </summary>
    /// <param name="Password"></param>
    /// <returns></returns>
    private static string Encrypt(string Password)
    {
      if (string.IsNullOrEmpty(Password))
        return string.Empty;

      byte[] Value = Encoding.UTF8.GetBytes(Password);
      SymmetricAlgorithm mCSP = new RijndaelManaged();
      mCSP.Key = _key;
      mCSP.IV = _initVector;
      using (ICryptoTransform ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV))
      {
        using (MemoryStream ms = new MemoryStream())
        {
          using (CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write))
          {
            cs.Write(Value, 0, Value.Length);
            cs.FlushFinalBlock();
            cs.Close();
            return Convert.ToBase64String(ms.ToArray());
          }
        }
      }
    }

    /// <summary>
    /// Looks up the users password crypto string in the database
    /// </summary>
    /// <param name="Username"></param>
    /// <returns></returns>
    private static DataTable LookupUser(string Username)
    {
      /*
       * The reason I return a datatable here is so you can also bring back the user's full
       * name, email address, security rights in the application, etc. I have a "User" class
       * where I defined meta information for users.
       */ 
      const string connStr = "Data Source=apex2006sql;Initial Catalog=Leather;Integrated Security=True;";
      const string query = "Select Password From UserTable (NOLOCK) Where UserName = @UserName";
      DataTable result = new DataTable();
      using (SqlConnection conn = new SqlConnection(connStr))
      {
        conn.Open();
        using (SqlCommand cmd = new SqlCommand(query, conn))
        {
          cmd.Parameters.Add("@UserName", SqlDbType.VarChar).Value = Username;
          using (SqlDataReader dr = cmd.ExecuteReader())
          {
            result.Load(dr);
          }
        }
      }
      return result;
    }

    /// <summary>
    /// Obviously the .Focus() code doesn't apply to ASP.NET
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void buttonLogin_Click(object sender, EventArgs e)
    {
      if (string.IsNullOrEmpty(textBoxUsername.Text))
      {
        //Focus box before showing a message
        textBoxUsername.Focus();
        MessageBox.Show("Enter your username", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        //Focus again afterwards, sometimes people double click message boxes and select another control accidentally
        textBoxUsername.Focus();
        return;
      }
      else if (string.IsNullOrEmpty(textBoxPassword.Text))
      {
        textBoxPassword.Focus();
        MessageBox.Show("Enter your password", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        textBoxPassword.Focus();
        return;
      }

      //OK they enter a user and pass, lets see if they can authenticate
      using (DataTable dt = LookupUser(textBoxUsername.Text))
      {
        if (dt.Rows.Count == 0)
        {
          textBoxUsername.Focus();
          MessageBox.Show("Invalid username.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
          textBoxUsername.Focus();
          return;
        }
        else
        {
          //Always compare the resulting crypto string or hash value, never the decrypted value
          //By doing that you never make a call to Decrypt() and the application is harder to
          //reverse engineer. I included the Decrypt() method here for informational purposes
          //only. I do not recommend shipping an assembly with Decrypt() methods.

          string dbPassword = Convert.ToString(dt.Rows[0]["Password"]);
          string appPassword = Encrypt(textBoxPassword.Text); //we store the password as encrypted in the DB
          if (string.Compare(dbPassword, appPassword) == 0)
          {
            //Logged in
          }
          else
          {
            //You may want to use the same error message so they can't tell which field they got wrong
            textBoxPassword.Focus();
            MessageBox.Show("Invalid Password", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
            textBoxPassword.Focus();
            return; 
          }
        }
      }
    }
  }
}
 
0
 

Very instructive for a C# learner like me.
I have already seen it pays off! You reffered to this snippet in another thread. Keep up the good spirit!

 
0
 

Very instructive! But I'm using the ASP.Net What we should use instead of .Focus()?

And when using built-in Login and CreateUserWizard controls where/in which databse, table does it store all the information? Can Access that table and add some fields manually? If yes, how can I access.

thanks in advance!

 
0
 

thanks for this code.......i willing to use it......can you please upload a simple MD5 encrypted login form with logout function.....i'm creating a software that needs user authentication to enter....using C#2008.....thank you again!!

 
0
 

You don't need to call .Focus() on ASP.NET or win forms applications, it just aesthetic. It won't kill the user to click ;)
You should be fine if you just put a red label with "Invalid username or password" and let them fix it. I included code to tell them which field they have wrong but I personally use the same error and focus the username field regardless so they can't guess at which fields are right or wrong.

Regarding the built in login controls and create wizard -- I don't know. I don't use them.

For md5 just swap out my encryption functions (and remove the decrypt function since md5 hashes, not encrypts). You can find an md5 haser at:

http://blog.stevex.net/index.php/c-code-snippet-creating-an-md5-hash-string/

 
0
 

thank you sknake

 
0
 

just now 1ly i stared studying c# i dont know the basic commands so tell me how to run the code..?

 
1
 

Open up visual studio, slap that code in to a form, and hit F5.

 
0
 

thanks for ur reply.......
we can not type the code using sdk command promt.....a?

 
2
 

Uhm.. maybe, but why would you want to inflict that pain on yourself? Just use the designer.

 
-1
 

i did slap the code in the visual studio click F5 but it can't work.
jeez i feel like a dummy. trying to figure out how the code work. haas.
and i still don't get it.

 
0
 

Sorry.. i have got problem to make it work..... need help..

It seem that, value that i entered into the textBoxPassword field doesn't pass the comparison done (string.Compare()) againt the value stored in the DB. (It keep on skip to the action in 'else if' statement. For instance, i have my Password in DB as 'abc', of course, to make match, i have then input the value in textBoxPassword field as 'abc' as well, However, it do keep on say 'invalid password'!!

I have got the Data Type for UserName and Password as nchar(10) in MSSQL DB.

Anything tht i had miss out?

 
0
 

how to intgrade Csharp code in c++ project...........plz reply

 
1
 

Quite helpful ! :)
There is one suggestion. You can add a functionality to check whether the same login is used by another user currently.

 
1
 

I'm new to c# and this forum. your work is great, wondering if you can help with filling a combobox using OOP approach with storedProcedures,this were you have a form with events class and a data access object which is directly interacting with the database then feeding the form. thanx

 
0
 

hi sir
I am creating website in asp.net. so i am creating the login window and one master page.
my problem is that i want to access this user name display in master page i am creating session or access it but when i am direct access master page then Run time error occur

 
0
 
SqlConnection con = new SqlConnection(strConn);
            string strCmd = "select UserName, Password from Login where UserName='" + txtUserName.Text + "' and Password ='" + txtPassword.Text + "'";
            SqlCommand cmd = new SqlCommand(strCmd, con);
            SqlDataAdapter da = new SqlDataAdapter(strCmd, con);
            DataSet ds = new DataSet();
            con.Open();
            cmd.ExecuteNonQuery();
            da.Fill(ds);
            con.Close();
            MessageBox.Show("Login successful", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
            frmLogin login = new frmLogin();
            login.Close();
            frmBill bills = new frmBill();
            bills.Show();
 
0
 

This is really fantastic Sknake. It is a ready to use login code.
Thanks for this and I would like to rate it 5/5. Keep it up.

 
0
 

I have used your code and can get it to work without encrypt. However I am have a hard time setting database up to encrypt Password field with same encryption that matches the code

Can someone help Thanks

 
0
 

hi good stuff

Isn't it about time forums rewarded their contributors?

Earn rewards points for helping others. Gain kudos. Cash out. Get better answers yourself.

It's as simple as contributing editorial or replying to discussions labeled or OP Kudos

You
This is an OP Kudos discussion and contributors may be rewarded
Post:
Start New Discussion
View similar articles that have also been tagged: