0

I am trying to create a simple asp.net website that allows users to register and log in. I have successfully managed to store all the data in the database and authenticate the user in the log in form. However the thing I want to do now is whenever a new user registers to store the password in the database in MD5 format and match the hashes in order for the user to be able to login.

This is the code in the register section that stores the user in the database:

try
    {
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["AssignmentDBConnectionString"].ConnectionString);
        conn.Open();
        string insertQuery = "insert into [AsTable] ([Username],Email,Password) values (@Username ,@Email, @Password)";
        SqlCommand com = new SqlCommand(insertQuery, conn);
        com.Parameters.AddWithValue("@Username", TextBoxUsername.Text);
        com.Parameters.AddWithValue("@email", TextBoxEmail.Text);
        com.Parameters.AddWithValue("@password", TextBoxPass.Text);

        com.ExecuteNonQuery();
        Response.Redirect("Manager.aspx");
        Response.Write("Registration Completed");

        conn.Close();

    }
    catch (Exception ex)
    {
        Response.Write("Error:"+ex.ToString());
    }

And this is the code in the login section that authenticates the user in order for him to login:

conn.Open();
        string checkPasswordQuery = "select Password from [AsTable] where Username ='" + TextBoxUsername.Text + "'";
        SqlCommand passcom = new SqlCommand(checkPasswordQuery, conn);
        string password = passcom.ExecuteScalar().ToString().Replace(" ","");
        if (password == TextBoxPassword.Text)
        {
            Session["New"] = TextBoxUsername.Text;
            Response.Write("Password is correct");
            Response.Redirect("Index.aspx");
        }
        else
        {
            Response.Write("Password is not correct");
        }
    }

    else
    {
        Response.Write("Username is not correct");
    }

}

Any ideas what to change??

rducom
  • 6,752
  • 1
  • 26
  • 37
michalis
  • 19
  • 1
  • 10
  • 7
    **warning** your 2nd example is vulnerable to sql injection attacks! – Daniel A. White Mar 13 '15 at 12:53
  • 1
    use the default sql membership provider instead of custom code – Ewan Mar 13 '15 at 12:55
  • 1
    Use SP and parameter queries. If not using the `using` syntax, I would close the connection in the finally{} block. – Tim Mar 13 '15 at 12:56
  • 2
    Why are you removing spaces from the password in your retrieval code? – D Stanley Mar 13 '15 at 12:58
  • 1
    "Any ideas what to change??" add MD5 encryption before saving the password and MD5 decryption when retrieving it. Should be lots of examples out there on how to do that. – D Stanley Mar 13 '15 at 12:59
  • Re: _"Any ideas what to change?"_ [Do not store passwords as plain text.](http://blog.codinghorror.com/youre-probably-storing-passwords-incorrectly/) Salt them and hash them (using a cryptographic hash). – stakx - no longer contributing Mar 13 '15 at 13:30
  • It is good to do MD5 calculation at client side and send the MD5 instead of plain text password. Otherwise it can be sniffed. – i486 Mar 13 '15 at 13:30

2 Answers2

3

this is how i deal with encryption

first i create a method to convert simple string to sha256 (i think this is better than md5)

public string ToSHA256(string value)
    {
        SHA256 sha256 =  SHA256.Create();

        byte[] hashData = sha256.ComputeHash(Encoding.Default.GetBytes(value));
        StringBuilder returnValue = new StringBuilder();

        for (int i = 0; i < hashData.Length; i++)
        {
            returnValue.Append(hashData[i].ToString());
        }

        return returnValue.ToString();
    }

then

just change your code in creating a user to

try
{
    SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["AssignmentDBConnectionString"].ConnectionString);
    conn.Open();
    string insertQuery = "insert into [AsTable] ([Username],Email,Password) values (@Username ,@Email, @Password)";
    SqlCommand com = new SqlCommand(insertQuery, conn);
    com.Parameters.AddWithValue("@Username", TextBoxUsername.Text);
    com.Parameters.AddWithValue("@email", TextBoxEmail.Text);
    com.Parameters.AddWithValue("@password", ToSHA256(TextBoxPass.Text));

    com.ExecuteNonQuery();
    Response.Redirect("Manager.aspx");
    Response.Write("Registration Completed");

    conn.Close();

}
catch (Exception ex)
{
    Response.Write("Error:"+ex.ToString());
}

then in retrieving password

conn.Open();
    string checkPasswordQuery = "select Password from [AsTable] where Username ='" + ToSHA256(TextBoxUsername.Text) + "'";
    SqlCommand passcom = new SqlCommand(checkPasswordQuery, conn);
    //string password = passcom.ExecuteScalar().ToString().Replace(" ","");
    if (password == ToSHA256(TextBoxPassword.Text))
    {
        Session["New"] = TextBoxUsername.Text;
        Response.Write("Password is correct");
        Response.Redirect("Index.aspx");
    }
    else
    {
        Response.Write("Password is not correct");
    }
}

else
{
    Response.Write("Username is not correct");
}
}
  • I copied and pasted this method to both registartion and login files but the name of the method "ToSHA256" turns red and says that not all code paths return a value!!! I have included the using System.Security.Cryptography; using System.Text; – michalis Mar 13 '15 at 13:17
0

I personally use a custom random number generator, a custom scrambler (able to unscramble) and an AES encryption, input is string, output is a base64 encoded binary password. (The best practice though is to save the hashed passwords in the database, and when authenticating, hash the provided password and check against database value)

int KeyLength = 16;
public static Int32 GetASeed(String SeedStr)
{
    Int32 Seed = 0;
    for (int i = 0; i < SeedStr.Length; i++)
    {
        Seed ^= SeedStr[i];
    }
    return Seed;
}

public static byte[] Keygen(String Str)
{
    Int32 Seed = GetASeed(Str);
    Random NumGenerator = new Random(Seed);
    byte[] Key = new byte[KeyLength];
    for (int i = 0; i < KeyLength; i++)
    {
        Key[i] = (byte)NumGenerator.Next(256);
    }
    return Key;
}

public static byte[] Encrypt(String Text, String Key)
{
    Aes Encryptor = Aes.Create();
    byte[] Data;
    Encryptor.Key = Keygen(Key);
    Encryptor.IV = Keygen(Key + "dec");
    Data = Encryptor.CreateEncryptor().TransformFinalBlock(Encoding.UTF8.GetBytes(Text), 0, Text.Length);
    return Convert.ToBase64String(Data);
}


public static String Decrypt(byte[] Data, String KeyPass)
{
    Aes Decryptor = Aes.Create();
    Decryptor.Key = Keygen(KeyPass);
    Decryptor.IV = Keygen(KeyPass + "dec");
    Data = Decryptor.CreateDecryptor().TransformFinalBlock(Data, 0, Data.Length);
    return Encoding.UTF8.GetString(Convert.FromBase64String(Data));
}

Usage:

Encrypt(SomePasswordField.Text, "MyWayCoolEnkryptionKeyString");
Decrypt(DatabaseUser.Password, "MyWayCoolEnkryptionKeyString");

This is just a skeleton of an AES encryption.

Felype
  • 2,967
  • 2
  • 23
  • 35