• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1610
  • Last Modified:

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 ?
  • 3
  • 3
2 Solutions
Assuming you are using a hashed password format you could add a new table, let's say "UserPasswordCache" where you can store the recently used password hashes alongside the users' primary key and see if you get a match there when a user tries to set a new password.
vu3lmgAuthor Commented:
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 ?
Just hook into ValidatingPassword event of the MembershipProvider class and store a MD5 or SHA hash of the password in your password history there if it's succesful. Also check if you're dealing with a valid and really new password there.
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

vu3lmgAuthor Commented:
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 ?
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;
    return false;

Open in new window

vu3lmgAuthor Commented:
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.

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now