locked
how to hash & salt password in Register and Login RRS feed

  • Question

  • User5146561 posted

    i am trying to make my website more secure and not store passwords as plain text. i looked at the example 'Username and hashed password authentication on login form C# ' on this site to try and incorporate it into my code but i keep getting conversion error  "Error converting data type nvarchar to uniqueidentifier.", also confused as to what data type should password and salt be stored in in the my database table?? Also i check if the users email isn't already in database to prevent them from registering twice with same email addr.

    here are my tables

    CREATE TABLE test(
    ID int identity(1,1) not null,
    Name nvarchar(50) not null,
    Surname nvarchar(50) not null,
    Email nvarchar(50) not null,
    Department nvarchar(max)null,
    Username nvarchar(50)null,
    Password nvarchar(50) not null,
    salt uniqueidentifier not null
    )

    my stored procedure:

    create PROCEDURE Reg
    @Name nvarchar(30),
    @Surname nvarchar(30),
    @Email nvarchar(50),
    @Department nvarchar(30),
    @username nvarchar(30),
    @Password nvarchar(50),
    @salt uniqueidentifier

    AS
    BEGIN
    SET NOCOUNT ON;

    IF EXISTS(SELECT ID FROM [test] WHERE [pb_Email] = @Email)
    BEGIN
    SELECT -2 -- Email exists.
    END
    ELSE
    BEGIN
    INSERT INTO [test]
    ([Name]
    ,[Surname]
    ,[Password]
    ,[Email]
    ,[Department]
    ,[Username]
    ,[salt])
    VALUES
    (@Name
    ,@Surname
    ,@Password
    ,@Email
    ,@Department
    ,@username
    ,@salt)
    END
    END

    and here is my code:

    protected void btnRegister_Click(object sender, EventArgs e)
        {
           
    
            int ID = 0;
            string password = Password.Text;
    
              System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
                byte[] saltBytes = new byte[36];
                rng.GetBytes(saltBytes);
                string salt = Convert.ToBase64String(saltBytes);
    
                byte[] passwordAndSaltBytes = System.Text.Encoding.UTF8.GetBytes(password + salt);
                byte[] hashBytes = new System.Security.Cryptography.SHA256Managed().ComputeHash(passwordAndSaltBytes);
                string hashString = Convert.ToBase64String(hashBytes);
    
                SqlConnection con = new SqlConnection(strConnString);
                con.Open();
    
                SqlCommand cmd = new SqlCommand("Reg", con);
    
                cmd.CommandType = System.Data.CommandType.StoredProcedure;
    
    
    
                cmd.Parameters.AddWithValue("@Name", Name.Text);
                cmd.Parameters.AddWithValue("@Surname", Surname.Text);
                cmd.Parameters.AddWithValue("@Email", txtEmail.Text);
                cmd.Parameters.AddWithValue("@Department", DropDwnDept.Text);
                cmd.Parameters.AddWithValue("@username", user.Text);
                cmd.Parameters.AddWithValue("@Password", password);
                cmd.Parameters.AddWithValue("@salt", salt);
                cmd.ExecuteNonQuery();
    
                con.Close();
    
    
                cmd.Connection = con;
                con.Open();
    
                ID = Convert.ToInt32(cmd.ExecuteScalar());
                try
                { 
    
                if (ID == -2)
                {
                    ClientScript.RegisterStartupScript(GetType(), "alert", "alert('Supplied email address has already been used.');", true);
                    txtEmail.Text = "";
    
                }
                else
                {
                    ClientScript.RegisterStartupScript(GetType(), "alert", "alert('Registration successful.');", true);
                    Response.Redirect("~/login.aspx");
    
                }
        
                con.Close(); 
                
            }
            catch (Exception) { }
          
        }
    }

    Tuesday, May 14, 2019 2:47 PM

Answers

  • User-821857111 posted

    Usually, the hashed password is Base64-encoded and stored as a simple string.

    I would recommend using methods written by exports rather than trying to roll your own, unless you know exactly what you are doing. The standard approach from MS is to generate a cryptographically safe salt, combine that with the password and then hash the result, Then they store the salt with the hash: https://www.mikesdotnetting.com/article/200/the-simplemembershipprovider-secure-passwords-and-the-crypto-helper

    You could do worse than borrow the source code for the HashPassword and VerfyHashPassword methos from the Crypto helper mentioned in the above article. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, May 14, 2019 2:59 PM

All replies