0

I am currently working on a project which has clear text passwords. Now we have the requirement to change all the clear text passwords to HASH. The Database has the password field and Password salt field.

I tried the following in .Net (I found .Net 4 uses HMACSHA256 algorithm) to hash the passwords with the salt already in the database.

// I retrieved the password and salt from database and hashed it
string authDetails = row["Password"] + row["PasswordSalt"].ToString(); //password salt - value from database 
byte[] authBytes = System.Text.Encoding.UTF8.GetBytes(authDetails);

var hma = new System.Security.Cryptography.HMACSHA256();
byte[] hashedBytes = hma.ComputeHash(authBytes);
string hash = Convert.ToBase64String(hashedBytes);

and stored the above hash var value in the password field.

And I changed the config setting passwordFormat="hashed".

If I try to login with the password, the login fails. I cannot login with old password. Any ideas?

Thanks!

EDIT: just for clarification.. I use asp.net membership provider. I changed the PasswordFormat to 'Hashed' in web.config. Then I call Membership.ValidateUser to validate the logon. - I think it automatically hashes the password entered and matches against database. But i suppose the generated hash by validateuser method is not the same as the hash I generated above.

user1165815
  • 305
  • 2
  • 6
  • 21
  • How are you telling the password checking algorithm which salt to use? – Robert Harvey Jun 04 '13 at 19:54
  • 1
    Not *quite* how you'd salt a hash... you basically hash the password, by giving the salt to the hash algo, rather than concatenating the password and the salt, and then hashing. – J. Steen Jun 04 '13 at 19:54
  • 3
    @J.Steen: Not necessarily. From the Wikipedia article on salting: "In a typical setting, the salt and the password are concatenated and processed with a cryptographic hash function". – Jon Skeet Jun 04 '13 at 19:57
  • if i don't use the same salt, how can i can hash the existing clear text passwords? Please correct me / please tell me how to achieve my goal? - without using the salt. – user1165815 Jun 04 '13 at 19:58
  • *...and stored the above hash var value in the password field* Does that mean next time you check the password you're rehashing the hash?? You probably need to clarify how the existing passwords were hashed, and how password entry is checked against those hashes. – PaulG Jun 04 '13 at 20:06
  • Use a proper password hash, such as PBKDF2. In .net `Rfc2898DeriveBytes` is the way to go. – CodesInChaos Jun 04 '13 at 21:04
  • @JonSkeet Alright. Not necessarily. =) – J. Steen Jun 04 '13 at 21:11
  • possible duplicate of [Convert ASP.NET Membership Passwords from Encrypted to Hashed](http://stackoverflow.com/questions/5798638/convert-asp-net-membership-passwords-from-encrypted-to-hashed) – jbtule Jun 05 '13 at 16:14
  • While you are converting plaintext to hashed, yours is even easier, by default the "Hashed" with the membership provider is just plain Sha1 (you can change it in the config), and the salt is prefixed not postfixed, and the salt is base64 encoded too, but the other question has an answer for this specifically. – jbtule Jun 05 '13 at 16:18

3 Answers3

2

HMAC is a keyed hash/a family of hashes. When you generate a new instance of it, .net initializes the key to a random value. So you get a different member of the family and thus different results.

In principle you could either switch to plain SHA256 or use the salt as key i.e. HMACSHA256(key=salt,message=password). But that's a bad idea.

You should use a specialized password hashing function, which is slow. See How to securely hash passwords? on security.SE for details on password hashing. In .net the there is Rfc2898DeriveBytes which implements PBKDF2-HMAC-SHA1.

Community
  • 1
  • 1
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • +1 The poster is technically asking how to migrate his existing builtin .net membership provider by change the setting to the crappy single hashed version of it, but I like your answer better. – jbtule Jun 05 '13 at 16:24
0

You dont need to use use hashmac, but just hash like sha256. Point in hashmack is that is used when key is used to authenticate message, but it is not needed for password salting, (hashmac takes extra parameter that is key)

All you need is

sha256(password + salt)
Luka Rahne
  • 10,336
  • 3
  • 34
  • 56
  • thanks , USed this to hash System.Security.Cryptography.SHA256CryptoServiceProvider(); (password+salt) even then i am not able to login – user1165815 Jun 04 '13 at 20:13
  • You said way to sore this password, how do you then check password against database? – Luka Rahne Jun 04 '13 at 20:41
  • I use asp.net membership provider. I changed the PasswordFormat to 'Hashed' in web.config. Then I call Membership.ValidateUser to validate the logon. - I think it automatically hashes the password entered and matches against database. But i suppose the generated hash here is not the same as the hash i generated above. – user1165815 Jun 04 '13 at 20:46
0

If I try to login with the password, the login fails. I cannot login with old password. Any ideas?

When you login, you trust that the supplied username is correct and use it to lookup that user's salt. Then you use the salt and the password entered by the user to compute the hash in the same way you did when updated the password in the first place. Now you can compare this to the stored password.

So you need code like this:

string GetSalt(string username)
{
    string sql = "SELECT PasswordSalt FROM [users] WHERE username= @username";
    //connect to database and return that result
}

string ComputeHash(string username, string password)
{
    string salt = GetSalt(username);

    //should actually concatenate byte arrays, not strings
    byte[] authBytes = System.Text.Encoding.UTF8.GetBytes(password + salt);
    var hma = new System.Security.Cryptography.HMACSHA256();
    byte[] hashedBytes = hma.ComputeHash(authBytes);
    return Convert.ToBase64String(hashedBytes);
}

bool Login(string username, string password)
{
    string hash = ComputeHash(username, password);

    string sql = "SELECT COUNT(*) FROM [users] WHERE username= @username AND Password= @Hash";
    // run that and make sure you get a row back

}
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • I changed the passwordFormat to 'Hashed' in web.config.. so the above step you mentioned will be automatically done by .net when I call Membership.ValidateUser, is that correct? – user1165815 Jun 04 '13 at 20:20
  • Oh good, you're using the membership provider. You need to read this: http://stackoverflow.com/questions/5798638/convert-asp-net-membership-passwords-from-encrypted-to-hashed – Joel Coehoorn Jun 04 '13 at 20:25