Click here to Skip to main content
12,635,662 members (26,579 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


105 bookmarked

Password Storage: How to do it.

, 29 Apr 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
A lot of people are asking how to encrypt passwords, and I have answered "Don't do it" too many times. This Tip describes how to store a password in your database, and why.
Why do I reply "Don't do it!" when asked how to encrypt passwords? Simple: it is a major security risk! However, I am definitely not suggesting that you should store passwords in plain text. Instead, you should use a hashing function on them, and store the result. Why:

  1. Storing passwords in plain text is simple, but a major security risk. Anyone who can get access to your database (and that is probably a lot more people than you think) gets every-bodies user ID and password, for free. Since many people can't remember more than one password, this gives them access to any system your user connects to, in theory. Not a good idea!
  2. Storing encrypted passwords is also a major security risk! Think about it: encryption requires decryption before it is any use. Which means your program must have access to the encryption key used to encrypt the password in the first place, every time you need to check if the user has entered the password correctly. There is a very good chance that anybody who has access to your database also has access to the executable and data files of your program, so the encryption key is effectively kept with the data it "protects". Not a good idea!

Instead, there is a class of cryptographic functions called "one-way functions" or "hashing algorithms". These do not work like encryption: there is no way to take the output of a hashing algorithm and work back to the entered password. You cannot decrypt a hashed value. The most common of these are MD5 and SHA, but MD5 has been shown to be "broken" - under some circumstances, you can get a workable input from the output. As a result, it is no longer recommended for new applications.

In addition, it is a good idea to include the user name or ID (whichever is unique in your system) in with the password in the data to hash, because it means that two users with the same password do not generate the same hash. Otherwise, the easy way to hack passwords is just: Try "Password". Does my hash in the database match any other users? No. Ok, try "password". And so on.

So: to hold the password in your database, create a VARBINARY column, 20 bytes long, called "Password".

Then add the following code:
/// <summary>
        /// If the two SHA1 hashes are the same, returns true.
        /// Otherwise returns false.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns></returns>
        private static bool MatchSHA1(byte[] p1, byte[] p2)
            bool result = false;
            if (p1 != null && p2 != null)
                if (p1.Length == p2.Length)
                    result = true;
                    for (int i = 0; i < p1.Length; i++)
                        if (p1[i] != p2[i])
                            result = false;
            return result;
        /// <summary>
        /// Returns the SHA1 hash of the combined userID and password.
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        private static byte[] GetSHA1(string userID, string password)
            SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
            return sha.ComputeHash(System.Text.Encoding.ASCII.GetBytes(userID + password));

To test it:
private static void RunTest()
            string userId = "OriginalGriff";
            string password = "NotMyPassword";
            string enteredPassword = "NotMyPassword";
            string notPassword = "notMyPassword";
            byte[] hashedPassword = GetSHA1(userId, password);
            if (MatchSHA1(hashedPassword, GetSHA1(userId, enteredPassword)))
                Console.WriteLine("Log him in!");
                Console.WriteLine("Don't log him in!");
            if (MatchSHA1(hashedPassword, GetSHA1(userId, notPassword)))
                Console.WriteLine("Will not happen!");
                Console.WriteLine("Don't log him in!");

You should get the output:
Log him in!
Don't log him in!

All you have to do now is write the hashed value into your database, and read it out for comparison when you want to log the user in.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Wales Wales
Born at an early age, he grew older. At the same time, his hair grew longer, and was tied up behind his head.
Has problems spelling the word "the".
Invented the portable cat-flap.
Currently, has not died yet. Or has he?

You may also be interested in...

Comments and Discussions

GeneralReason for my vote of 5 Well done! Pin
Espen Harlinn5-Feb-12 10:08
mvpEspen Harlinn5-Feb-12 10:08 
GeneralReason for my vote of 5 good one Pin
S.P. Tiwari12-Dec-11 2:26
memberS.P. Tiwari12-Dec-11 2:26 
GeneralReason for my vote of 5 Awesome stuff! I wish they would put... Pin
Slacker00724-Jun-11 0:58
memberSlacker00724-Jun-11 0:58 
GeneralIt's good that you mention hashing with the user id since it... Pin
Patrick Persson9-May-11 15:04
memberPatrick Persson9-May-11 15:04 
GeneralHmmm, but isn't it that Sony stored passwords hashed and cre... Pin
ivanicin3-May-11 12:39
memberivanicin3-May-11 12:39 
GeneralWhat if you're working within an API or other framework wher... Pin
kamahl3-May-11 6:01
memberkamahl3-May-11 6:01 
GeneralAdding the username into the hash is a good point. However, ... Pin
Jaepetto2-May-11 22:49
memberJaepetto2-May-11 22:49 
GeneralDo not use MD5 or SHA1 to hash passwords. This has been prov... Pin
I'm Chris2-May-11 21:38
memberI'm Chris2-May-11 21:38 
Do not use MD5 or SHA1 to hash passwords. This has been proven to be too weak given today's processing power (GPU, cloud computing...). Instead, people have been using for a while now what they call "slow" algorithms to defeat reverse hashing - namely BCrypt and Scrypt. You'll easily find good explaination and .NET implementations on the net.

SuggestionRe: Do not use MD5 or SHA1 to hash passwords. This has been prov... Pin
SAKryukov3-Mar-12 13:59
mvpSAKryukov3-Mar-12 13:59 
GeneralMessage Removed Pin
DutchMafia30-Apr-11 8:25
memberDutchMafia30-Apr-11 8:25 
GeneralIn your text you say to use a 20Byte VarBin, surely you need... Pin
DaveAuld29-Apr-11 22:53
mentorDaveAuld29-Apr-11 22:53 
GeneralRe: That's why I was thinking of expanding / re-writing it to an... Pin
OriginalGriff29-Apr-11 23:00
mvpOriginalGriff29-Apr-11 23:00 
GeneralGood point regarding passwords. One other point I would add ... Pin
Atlas200229-Apr-11 20:52
memberAtlas200229-Apr-11 20:52 
GeneralGood one OG Pin
thatraja25-Apr-11 5:54
mvpthatraja25-Apr-11 5:54 
GeneralRe: Sorry about that - I clicked the wrong reply button! :blush: Pin
OriginalGriff25-Apr-11 9:47
mvpOriginalGriff25-Apr-11 9:47 
GeneralGreat tip! BTW: assuming the username is case-insensitive, ... Pin
Luc Pattyn25-Apr-11 5:39
mvpLuc Pattyn25-Apr-11 5:39 
GeneralRe: Good points! Since I normally get the username from the DB u... Pin
OriginalGriff25-Apr-11 10:05
mvpOriginalGriff25-Apr-11 10:05 
Generalthanks for sharing - have 5 Pin
Pranay Rana25-Apr-11 4:54
memberPranay Rana25-Apr-11 4:54 
GeneralA sligthly off-topic thought... Pin
BarrRobot2-May-11 15:23
memberBarrRobot2-May-11 15:23 
GeneralRe: A sligthly off-topic thought... Pin
OriginalGriff2-May-11 22:20
mvpOriginalGriff2-May-11 22:20 
GeneralJust a thought [modified] Pin
kornman0030-Apr-11 6:08
memberkornman0030-Apr-11 6:08 
GeneralGood advise; a couple of comments Pin
Rob Smiley25-Apr-11 4:55
memberRob Smiley25-Apr-11 4:55 
GeneralRe: Good advise; a couple of comments Pin
OriginalGriff25-Apr-11 10:04
mvpOriginalGriff25-Apr-11 10:04 
General[My vote of 2] Salting and iterating Pin
John P Cronan25-Apr-11 4:45
memberJohn P Cronan25-Apr-11 4:45 
GeneralRe: [My vote of 2] Salting and iterating Pin
OriginalGriff26-Apr-11 0:06
mvpOriginalGriff26-Apr-11 0:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.161208.2 | Last Updated 29 Apr 2011
Article Copyright 2011 by OriginalGriff
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid