Monday, September 3, 2007

Saving passwords in a database? No!

So how can it be handled in a better way technically speaking? Referencing to the previous post.

Saving passwords in a database as plain text is really a bad idea. Should the passwords be stored in the database encrypted? No, that is not safe either.

Hashing is the way to go. In .NET System.Security.Cryptography you can convert the password into hashes using SHA1 or MD5. Hashing algorithms are one-way, so there is no
way to "unhash" something into a password again if you need to retrieve it. The only thing that can be done is to validate that the password is correct by hashing it and comparing it to the saved hash value. That is why some sites offer you to reset the password but they cannot show you your password.

System.Web.Security namespace has the FormsAuthentication.HashPasswordForStoringInConfigFile Method.

Dim hashedPassword As String
hashedPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(password.Text, hashMethod)

hashMethod can be either "MD5" or "SHA1"

Example: hashing the password 'test' gives the hash: 'ogF4I9nCJZCyYFP0azRLIS5wbvFdmlaHt5krTFW9RirYCdC3SgLbhngWGxYHOKXQ'

But this is still not enough. What if two or more users has the same password. That means that if you manage to get the password from one user you automatically have the password for other users with the same password. This can be exploited in a so called dictionary attack. Why is that? Most users actually uses simple passwords that exists in a dictionary. What the hacker does is to create hashes of a lot of words or passwords and can then compare these hashes to the hashes saved in the database.

Salting hashes is the next step to take. That means that a random string is generated and combined with the password and then hashed. So each user credential row has both a hash as well as a random salt string saved in the database. This will make all hashes unique.

Example: hashing the password 'test' combined with the salt 'Djf983jDJ#64)-d2' gives the hash: '57cjEal0b2+hNRT4sLc2eHL6m/0omTpKk8bkSF8osu9mNF0HG+H6HMFHYzzcR6RR'

This makes it a lot harder for the hacker since he would have to hash all his maybe 1,000,000 dictionary entries with the salt of every user row. That will take so much more time.

So the tip for those that want makes websites that needs to register users or needs to validate passwords one way or the other, do not ever save a clear text password in your database, hash it and use a bit of salt.

There are also other ways to handle web authentication. Take a look at Windows CardSpace and OpenID. OpenID is something you will see more of on Internet, that is for sure.

Update. You can read these posts including comments for more detailed information. Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes and 2 posts by Coding Horror, Rainbow Hash Cracking and You're Probably Storing Passwords Incorrectly


Some of the latest blog posts

Subscribe to RSS headline updates from:
Powered by FeedBurner