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
Adam Tuliper 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)

0
securecurve 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