Link to home
Start Free TrialLog in
Avatar of vu3lmg
vu3lmgFlag for United States of America

asked on

prevent past used passwords while changing

I am developing a web application using ASP.NET, VS 2008, framework 3.5
I am using sql membership provider for user authentication.
When a user is changing his password, I want to prevent him using previously used passwords.
How to implement this ?
ASKER CERTIFIED SOLUTION
Avatar of tillgeffken
tillgeffken

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of vu3lmg

ASKER

tillgeffken
I am thinking of doing that,  just wanted to know if there is an easy way around .
Any examples or code downlodable from the net ?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of vu3lmg

ASKER

tillgeffken
In the ValidatingPassword  event, args.Password property returns unhashed-new-password.
In the history table old passwords are stored in the hashed format.
How do I compare these ?
Avatar of tillgeffken
tillgeffken

The membership provider does some funky stuff in the hashing procedure. Please test attached code and see if it works, really not sure here. You need to store the salt used for hashing the individual passwords,retrieve and pass it to the method below. Do this for every password stored in your history.

Another approach would be to not store the membership provider hash in the history but a hash generated by you that is more easily to reconstruct. But before you do that make sure you evaluate the security implications.

public static bool ComparePasswordHashes(string newPassword, string saltValue, string oldPasswordHash)
{  
  byte[] saltValueBytes = System.Convert.FromBase64String(saltValue);
  byte[] plainTextBytes = System.Text.Encoding.Unicode.GetBytes(newPassword);
 
  byte[] saltValueBytesWithPlainTextBytes = new byte[saltValueBytes.Length + plainTextBytes.Length];
  System.Buffer.BlockCopy(saltValueBytes, 0, saltValueBytesWithPlainTextBytes, 0, saltValueBytes.Length);  
  System.Buffer.BlockCopy(plainTextBytes, 0, saltValueBytesWithPlainTextBytes, saltValueBytes.Length, plainTextBytes.Length);
 
  byte[] hashBytes = new System.Security.Cryptography.SHA1CryptoServiceProvider().ComputeHash(saltValueBytesWithPlainTextBytes);
  string computedHash = Convert.ToBase64String(hashBytes);
 
  if (computedHash == oldPasswordHash)
    return true;
  else
    return false;
}

Open in new window

Avatar of vu3lmg

ASKER

tillgeffken
To avoid all this conversion (Hashing the password) I decided to do following (let the provider Hash the password and I deal with hashed passwords only).

* I created a table called "Password History" to store current and past password Hashes for each user.
* I modified the "aspnet_Membership_SetPassword" to do 2 things.
          1) Check the "Password History" table for matching Password Hash, if found return failure, do not Set the new password.
          2) If the password is not a repeat, store the password hash in a "Password History" table for future comparision, return success.

It seem to be working fine.  
Any comments / suggestions on this.
I will wait for your comments before closing the question.