0

I'm trying to create a login page. I have managed to do the register page and store the email and the encrypted password but I'm struggling to do the login page to check the user exists and the password is correct. I think I've got it completely wrong but hoping some one will show me the correct code as I'm new this.

This is the stored procedure I created for logging in:

CREATE PROCEDURE [dbo].[Logged]
    @Email NVARCHAR (50),
    @Password NVARCHAR (50)
AS
BEGIN
    SELECT * 
    FROM [dbo].[Register] 
    WHERE [Email] = @Email 
      AND [Password] = @Password
END 
GO

Here is the login.aspx.cs code.

public string CheckPasswordQuery { get; private set; }

public string ToSHA2569(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();
    }

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        try
        {
            using (SqlConnection sqlcon = new SqlConnection(connectionString))
            {
                sqlcon.Open();
                SqlCommand cmd = new SqlCommand("Logged", sqlcon);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@Email", txtEmail.Text.Trim());
                cmd.Parameters.AddWithValue("@Password", ToSHA2569(txtPassword.Text.Trim()));
                cmd.ExecuteNonQuery();

                if(CheckPasswordQuery == ToSHA2569(txtPassword.Text))
                {
                }
            }
        }
    }

I'd be grateful if someone would be able to help me with this

UPDATE: is this code any closer? I really appreciate any help

protected void btnSubmit_Click(object sender, EventArgs e)
{
    try
    {
        using (SqlConnection sqlcon = new SqlConnection(connectionString))
        {
            string user = txtEmail.Text;
            string pass = ToSHA2569(txtPassword.Text);

            sqlcon.Open();

            SqlCommand cmd = new SqlCommand("select @Email,@Password from [dbo].[Register] where Email=@Email and Password=@Password", sqlcon);
            cmd.Parameters.AddWithValue("@Email", txtEmail.Text);
            cmd.Parameters.AddWithValue("@Password", ToSHA2569(txtPassword.Text));

            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            da.Fill(dt);

            if (txtEmail.Text ==  )
            {
                sqlcon.Close();
                Response.Redirect("default.aspx");
            }
            else
            {
                sqlcon.Close();
            }
        }
    }
    catch (Exception ex)
    {
        lblWrong.Text = "Something went wrong please try again later";
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Joe
  • 5
  • 1
  • 8
  • This really belongs to Code Review, IMO. – Roger Wolf Dec 04 '18 at 02:50
  • you should read https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.executescalar?redirectedfrom=MSDN&view=netframework-4.7.2#System_Data_SqlClient_SqlCommand_ExecuteScalar and change your inline SQL to be something like "select count(*) from ..." – 2174714 Dec 04 '18 at 03:09

2 Answers2

0
 private void btnSubmit_Click(object sender, EventArgs e)
    {

        try
        {
            using (SqlConnection sqlcon = new SqlConnection(connectionString))
            {

                //string user = txtEmail.Text;
                //string pass = ToSHA2569(txtPassword.Text);
                sqlcon.Open();
                SqlCommand cmd = new SqlCommand("select count(*) from [dbo].[Register] where Email=@Email and Password=@Password", sqlcon);
                cmd.Parameters.AddWithValue("@Email", txtEmail.Text);
                cmd.Parameters.AddWithValue("@Password", ToSHA2569(txtPassword.Text));

                var isCorrectPassword = cmd.ExecuteScalar();
                if ((int)isCorrectPassword >= 1)
                {
                    //sqlcon.Close();  //taken care of because of the using command
                    Response.Redirect("default.aspx");
                }
                else
                {
                //    sqlcon.Close();
                  lblWrong.Text = "Password not correct";
                }
            }
        }

        catch (Exception ex)
        {
            lblWrong.Text = "Something went wrong please try again later";
        }
    }

Didn't correct some of the other things, but you might want to look at https://learn.microsoft.com/en-us/previous-versions/ff184050(v=vs.140)

2174714
  • 288
  • 2
  • 10
  • you are on the right track. i would consider another change - after this one - where I put the VAR and IF....it could say VAR...sqlcon.Close() (you want to close SQL as fast as possible for a different thread to use) and the the IF. inside the IF, you can remove the sqlcon.close...and the ELSE { }. and, the IF could be rewritten to if (...>=1) since it looks like you are saving all user id and passwords and might have duplicates. let me know if you want me to edit the answer to show you (want to stay with the Question) – 2174714 Dec 05 '18 at 00:58
  • yes please would you be able to edit the code for me – Joe Dec 05 '18 at 21:09
0

Problem with @Password NVARCHAR (50), This will take only first 50 chars in hashed password.

        StringBuilder Sb = new StringBuilder();

        using (SHA256 hash = SHA256Managed.Create())
        {
            Encoding enc = Encoding.UTF8;
            Byte[] result = hash.ComputeHash(enc.GetBytes(value));

            foreach (Byte b in result)
                Sb.Append(b.ToString("x2"));
        }

        return Sb.ToString();

Then use @Password NVARCHAR (64)

Read for this for more info How long is the SHA256 hash?

cdev
  • 5,043
  • 2
  • 33
  • 32
  • Normally you'd just Base64 the hash - need something like 52 characters and less code... Also the fact that 50 characters of hash are stored in DB is not a huge problem - OP could simply use first 50 characters in both cases (create / check).. – Alexei Levenkov Dec 04 '18 at 03:40