How to compare this Salted password when user logs in?

3.7k Views Asked by At

I've used this method to get salted password. I don't know how I can compare the stored salted password with user entered password when he/she logs in

string salt = GetRandomSalt();
 string passwordHash = HashPassword(txtPassword.Text, salt);
 IdentityResult result = manager.Create(user, passwordHash);


    public String GetRandomSalt(Int32 size = 12)
    {
        var random = new RNGCryptoServiceProvider();
        var salt = new Byte[size];
        random.GetBytes(salt);
        return Convert.ToBase64String(salt);
    }
    public String HashPassword(String password, String salt)
    {
        var combinedPassword = String.Concat(password, salt);
        var sha256 = new SHA256Managed();
        var bytes = UTF8Encoding.UTF8.GetBytes(combinedPassword);
        var hash = sha256.ComputeHash(bytes);
        return Convert.ToBase64String(hash);
    }

My application is ASP.net MVC 4 and uses identity framework to provide roles and users

I tried using the following code in login form, but it's not working. I guess it's because the manager.Create hashes the salted hash again. How to fix it?

Login.aspx

  bool pwmatch = VerifyPassword(txtUserName.Text, txtPassword.Text);


    public String HashPassword(String password, String salt)
    {
        var combinedPassword = String.Concat(password, salt);
        var sha256 = new SHA256Managed();
        var bytes = UTF8Encoding.UTF8.GetBytes(combinedPassword);
        var hash = sha256.ComputeHash(bytes);
        return Convert.ToBase64String(hash);
    }

    private bool VerifyPassword(string suppliedUserName, string suppliedPassword)
    {
        var userStore = new UserStore<IdentityUser>();
        userStore.Context.Database.Connection.ConnectionString =
            ConfigurationManager.ConnectionStrings["MUSICConnectionString"].ConnectionString;

        var manager = new UserManager<IdentityUser>(userStore);

        var user = manager.FindByName(suppliedUserName);
        bool passwordMatch = false;
        string dbPasswordHash = user.PasswordHash;
        int saltSize = 12;
        string salt =dbPasswordHash.Substring(dbPasswordHash.Length - saltSize);
        string hashedPasswordAndSalt =HashPassword(suppliedPassword, salt);
        // Now verify them.
        passwordMatch = hashedPasswordAndSalt.Equals(dbPasswordHash);
        return passwordMatch;
    }
2

There are 2 best solutions below

0
On

The main idea to use a salt for a specific user/password, but being able to retain the used salt when user logs in again. Here are the logical steps needed to do that:

To Store a Password

  • Generate a long random salt.
  • Prepend the salt to the password and hash it with a standard password hashing function.
  • Save both the salt and the hash in the user's database record.

To Validate a Password

  • Retrieve the user's salt and hash from the database.
  • Prepend the salt to the given password and hash it using the same hash function.
  • Compare the hash of the given password with the hash from the database. If they match, the password is correct. Otherwise, the password is incorrect.

Ref: https://crackstation.net/hashing-security.htm

0
On

Notice here how the default hash implementation in Identity is working ASP.NET Identity default Password Hasher, how does it work and is it secure?

ASP.NET Identity already contains a method to verify hashed password - its called VerifyHashedPassword you should be able to use this (unless you migrated in a particular way from prior asp.net membership)