views:

291

answers:

6

Some time ago I joined new project. It was under development for quite a long time. The thing that surprised me was that all users' passwords are stored in non-encrypted form.

I explained huge security vulnerabilities of this to our management - it looks like they agree with that and want to make project more secure. Team members agree too.

We have about 20K users in the system.

Actually it is quite stressful to make this work - migrate non-encrypted passwords to encrypted form. If something goes wrong it can lead to project's disaster.

How can I lower this stress? Backup? Unit-tests(integrational tests)?

A: 

If possible you can try this: Send out an email to all your users to update their passwords with a time-out period, after which they cannot work if they do not change their passwords. Hash these new passwords and store the hash. This would require some changes on the frontend (i.e. the data it sends back).

dirkgently
I don't like this solution, because it puts burden to the users. It conveys the following message to the users: ,,we've realized that we were providing you a bad system, so we are fixing it now, and we feel entitled to bother you and waste your time with e-mails and password-changing requests -- if you don't act, you'll lose access to your account because of our fault''
pts
I don't think the users will need to know anything except for the fact that they need to update their passwords -- which is a good thing to do IMO. And also, the old passwords -- they are a bomb ticks away from a blast.
dirkgently
I did not say they will lose their accounts. All I indicated was the system impose the password change after a given period of time. I have seen quite a few financial sites do this -- they are very, very particular when it comes to changing passwords after every 'x' weeks.
dirkgently
+5  A: 

Well, be careful with your backup because it will contain unencrypted user passwords :-)

Assuming that the passwords are stored in a database, an easy solution would go something like this:

1) Make a secure backup of the entire table data

2) Create new column (PasswordEncrypted or similar name)

3) Use an UPDATE query to update each row's new column with an MD5 of the unencrypted password while using a 32 byte or larger salt. Pretty much every database system today has an MD5 function so you won't even have to leave your SQL prompt

4) Keep the plaintext column in the interim and update your application/scripts accordingly to work with the salted password.

5) Rename the plaintext old password column to temporarily take it out of play and test your application- if there are any problems then go back to step 4 and fix your mistakes.

6) When everything is working properly drop the plaintext password column

7) Encourage users to pick a new password now that you have some level of security in place to mitigate the effects of any previous attacks which may have been successful.

Robert Venables
+1  A: 

Write lots of tests, that test lots of corner cases (upper and lower case, numbers, symbols, Unicode characters, long passwords, etc). When you're developing and testing, create a system to move back to the old system (by providing the old password list, of course, since once the passwords are hashed you won't be able to convert them back directly). Save a copy of the current password list. Convert the passwords over in a test file or test database, and then use the saved copied of the passwords to test that everything worked. Now move the system into production, and make sure it works for your users. If it does not, you have already tested the plan for migrating back to the old system. Once it has been demonstrated to work for a couple of weeks, you can delete the cleartext password list and you're all set.

Brian Campbell
+1  A: 

I would just hash the current passwords, store them in a new database field, and begin using that field while deleting the password field. I would then notify my users that now would be a good time to change passwords as you've implemented more security mechanisms to keep their data safe.

To have a backup, just do SELECT * INTO Backup FROM UserData

Joe Philllips
+1  A: 

You can get extra confidence by running both authentication methods (encrypted and unencrypted) for each login attempt, and if they yield a different outcome, get an alert e-mail sent to you. This change is not visible to your users, so it can run for weeks and even months. Once you see that the old and the new authentication works for a high enough percentage of your users, deactivate the old one.

pts
+2  A: 

What sort of project is this? A web application, desktop application?

If you're going down the refactoring road, is there a reason that the passwords need to be stored in something reversible like encryption? In general, it's good practice to hash your passwords with something like SHA then hash the input with the same algorithm and compare the results. You only store the hashed values, not the actual passwords. This gives you the ability to check that someone has entered the correct password without exposing your users to the possibility of your encryption being broken and their passwords exposed.

Specific information about your approach isn't something I can provide (since I don't know how it works), but your best bet is to create an additional column to store the hashed passwords, hash the existing passwords, then keep them up to date with any password changes. Use this new column for all new development, then once the move is complete and tested, delete the column with the plaintext passwords.

Adam Robinson