0

I was trying to use scrypt in asp.net for hashing the passwords from users, in the database, after sign up, but when I try to login, I don't know exactly how to compare the password for user with the hash from database.

Can anyone help me figure it out how to compare a password against a hashed password?

For SIGN-UP I used:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
using System.Drawing;
using System.Security.Cryptography;
using Scrypt;

namespace WebApplication1
{
    public partial class SignUp : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {


        }



        protected void btSignup_Click(object sender, EventArgs e)
        {
            if (tbUname.Text != "" & tbPass.Text != "" && tbName.Text != "" && tbEmail.Text != "" && tbCPass.Text != "")
            {
                if (tbPass.Text == tbCPass.Text)
                {
                    String CS = ConfigurationManager.ConnectionStrings["MyDatabaseConnectionString1"].ConnectionString;
                    using (SqlConnection con = new SqlConnection(CS))
                    {
                        ScryptEncoder encoder = new ScryptEncoder();
                        string hashsedPassword = encoder.Encode(tbPass.Text);
                        SqlCommand cmd = new SqlCommand("insert into Users values('" + tbUname.Text + "','" + hashsedPassword + "','" + tbEmail.Text + "','" + tbName.Text + "')", con);
                        con.Open();
                        cmd.ExecuteNonQuery();

                        lblMsg.Text = "Registration Succesfull";
                        lblMsg.ForeColor = Color.Green;
                        Response.Redirect("~/SignIn.aspx");
                    }
                }
                else { lblMsg.Text = "Passwords do not match"; }
            }

            else
            {
                lblMsg.ForeColor = Color.Red;
                lblMsg.Text = "All Fields are Mandatory";

            }
        }

        protected void Button1_Click(object sender, EventArgs e)
        {

            SqlConnection con1 = new SqlConnection();
            con1.ConnectionString = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\MyDatabase.mdf;Integrated Security=True";
            con1.Open();
            SqlCommand cm1 = new SqlCommand();
            cm1.CommandText = "select * from [Users]where Username=@Uname";
            cm1.Parameters.AddWithValue("@Uname", tbUname.Text);
            cm1.Connection = con1;
            SqlDataReader rd = cm1.ExecuteReader();
            if (rd.HasRows)
            {
                Label1.Visible = true;
                Label1.Text = "Username already exists !";
                Label1.ForeColor = System.Drawing.Color.Red;
            }

            else
            {
                Label1.Visible = true;
                Label1.Text = "Username is available !";
                Label1.ForeColor = System.Drawing.Color.Green;
            }
        }
    }
}

And LOGIN:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;

namespace WebApplication1
{
    public partial class SignIn : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }


        protected void Button1_Click(object sender, EventArgs e)
        {
            String CS = ConfigurationManager.ConnectionStrings["MyDatabaseConnectionString1"].ConnectionString;
            using (SqlConnection con = new SqlConnection(CS)) {
                SqlCommand cmd= new SqlCommand("select * from Users where Username='"+ Username.Text+"' and Password='"+Password.Text+"'" , con);
                con.Open();
                SqlDataAdapter sda = new SqlDataAdapter(cmd);
                DataTable dt = new DataTable();
                sda.Fill(dt);
                if (dt.Rows.Count != 0)
                {
                    Session["USERNAME "] = Username.Text;
                    Response.Redirect("~/UserHome.aspx"); }
                else {
                    lblError.Text = "Invalid Username or Password !";

                }
            }
        }
    }
}
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Alex.d
  • 1
  • 3
  • Sign-UP: http://pastebin.com/CQnjUZZd – Alex.d May 22 '16 at 11:45
  • Sign-IN : http://pastebin.com/aAJ9GUVQ – Alex.d May 22 '16 at 11:46
  • I use the package Scrypt.NET, in VS2012, with the functions : Generating a new hash for a password: ScryptEncoder encoder = new ScryptEncoder(); string hashsedPassword = encoder.Encode("mypassword"); Comparing a password against a hashed password: ScryptEncoder encoder = new ScryptEncoder(); bool areEquals = encoder.Compare("mypassword", hashedPassword); But I don't know how to integrate the part with "comparing" in my code, in the SIGN-IN. – Alex.d May 22 '16 at 12:04
  • That's fine. So, can you help me with a solution for my problem ? – Alex.d May 22 '16 at 12:30

1 Answers1

0

Scrypt.NET handles the comparison of the typed in password and the existing hash for you. The documentation page shows:

ScryptEncoder encoder = new ScryptEncoder();

bool areEquals = encoder.Compare("mypassword", hashedPassword);

In your case that means that you cannot use the password in the SQL query to get a specific user. You would have to use only the given Username to find the correct row in the Users table.

SqlCommand cmd = new SqlCommand("select * from Users where Username=@Username" , con);
cmd.Parameters.Add("@Username", SqlDbType.NVarChar, 255, Username.Text);

con.Open();
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
if (dt.Rows.Count != 0) {
    ScryptEncoder encoder = new ScryptEncoder();

    foreach(DataRow row in dt.Rows)
    {
        if (encoder.Compare(Password.Text, (string)row["Password"]))
        {
            Session["USERNAME "] = Username.Text;
            Response.Redirect("~/UserHome.aspx");
            return;
        }
    }
} else {
    lblError.Text = "Invalid Username or Password !";
}

Always use parametrized SQL queries. Otherwise, you're open to SQL injection attacks.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • I have no idea if this code for accessing the DataTable is correct. If you see an error, please correct it. – Artjom B. May 22 '16 at 14:49
  • It shows me 2 errors at " if ( encoder.Compare(Password.Text, row["Password"])) " : 1. The best overloaded method match for 'Scrypt.ScryptEncoder.Compare(string, string)' has some invalid arguments. Argument 2: cannot convert from 'object' to 'string' – Alex.d May 22 '16 at 16:46
  • Casting to string should suffice here. – Artjom B. May 22 '16 at 17:22
  • If this answer solved the problem in this question, you may [accept](http://meta.stackexchange.com/q/5234/266187) the answer. – Artjom B. May 26 '16 at 18:32