Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop User from using last 5 password?

I have a requirement to force a user to change password after 90 Days. This is working fine with something like the below:

if (memberUser.LastPasswordChangedDate.Date.AddDays(90) < DateTime.Now.Date)
{
     return RedirectToAction("MyChangePasswordMethod", "MyController");
}

However another requirement that I have is that the last 5 passwords a user has used cannot be repeated - does asp.net come with anything like this built in? I cant see anything in the aspnet db table where last previous passwords are stored. Will it be a matter of me storing the last password values in my own db table and then doing a compare against the new password field entered against the values for the user in my own custom db table?

like image 974
Ctrl_Alt_Defeat Avatar asked Feb 25 '13 11:02

Ctrl_Alt_Defeat


1 Answers

As you've spotted there's nothing built in so you'll have to store the previous passwords - make sure they're hashed or encrypted - for a user and check that list to make sure they aren't reusing one. Make sure you use the same salt for the hashing/encryption otherwise you'll never get a match for the same password.

I'd store all their previous passwords. This means you don't have to clear old data out of the table when they hit 5 changes and if the requirement changes to not reuse the last 10 or 15 changes you'll have the data. If you also store the date the password was changed you can build in a check to say no reuse in the last 12 months instead.

As you are storing the hashed/encrypted password and checking against that there's no chance of getting the plain text version out of your system.

I'd have a table of "UserId", "Password" and "DateChanged". Then you can find the last N passwords for this user and compare the hashed/encrypted version of the new password against this list:

var encryptedPassword = MembershipProvider.EncryptPassword(password);
int numberOfReuse = 5;  // or configurable
var historiesQuery = (from histories in dataContext.GetTable<PasswordHistory>()
                      where histories.UserId == userId
                      orderby histories.PasswordDate descending
                      select histories.Password).Take<string>(numberOfReuse);

return historiesQuery.Contains<string>(enycryptedPassword);

This returns true if the password has been used already.

To do the date based check:

var encryptedPassword = MembershipProvider.EncryptPassword(password);
DateTime testDate = DateTime.Now.AddMonths(-12);  // configurable
var historiesQuery = (from histories in dataContext.GetTable<PasswordHistory>()
                      where histories.UserId == userId
                      and histories.PasswordDate >= testDate
                      orderby histories.PasswordDate descending
                      select histories.Password);

return historiesQuery.Contains<string>(enycryptedPassword);
like image 170
ChrisF Avatar answered Oct 10 '22 15:10

ChrisF