Storing password in plain text, you’re doing it wrong

Hacking for password</p>
<p> If you’re software developer then there is big chance you’ll implement user login feature, and you must store the username and password in your system. Most of developers stored these precious information in database as plain text, yes we did include myself I was doing it wrong, and if you’re doing it please stop and read this article to know how to do it right and being awesome.

Username, Password, or Pin codes these are precious information, and if hacker or even internal employee stole the database he can do whatever he wants with your users information. So How to keep these information safe? The answer is hashing it.

Why I was not doing that? I was lazy and every time I googled/binged/searched about this, I found many complex How-To articles, but last week I finally found something simple and it’s the reason I’m writing this article.

What is hashing?

Hashing is encoding string “message” to hash value and you can’t reproduce the original string “message” from hash value, so it’s one way cryptographic algorithm, it’s different than encryption that it’s  two way cryptographic algorithm.

How to Hash password?

As I mentioned above I found many articles about how-to hash password but most of them are very complex and I believe in work smart not hard, I found System.Web.Helpers Namespace that has Crypto Class that has many hashing helpers. I play with it and try to learn how to hash a password.

Flow:

Now let’s understand the flow and then check how to implement it in code. First to save password in database you must hash it using one of hashing algorithm and store the hashes password into database.

StoreHashedPassword

Second to check the user password in login, you should hash the password user input and compare the two hashed passwords (user input & stored in database).

RetreiveHashedPassword

Code:

I’ll show you how to hash user’s password and check the password he’ll enter when login to your system. Like I said above I’ll user System.Web.Helpers.Crypto Class, this class has 2 methods HashPassword and VerifyHashedPassword we’ll use them. we’ll write the code in Unit Tests so no need for Console Application and wait for Command Prompt to run, you’ll just write your code test it and you’ll get results in test results quickly, so let’s get our hand dirty:

Hash:

What you need to do is to pass the user input password to HashPassword() Method and you’ll get the hashed password.

   1:   plainPassword = "P@12345566";
   2:   hashedPassword = Crypto.HashPassword(plainPassword);

Compare:

We can verify the password by passing the hashed password and the plain password and VerifyHashedPassword() Method will return true if it’s verified or false if it’s not.

   1:  Assert.AreEqual(true, Crypto.VerifyHashedPassword(hashedPassword,plainPassword));

Complete Code:

   1:  [Test]
   2:  public void test_hashing_password()
   3:  {
   4:      string plainPassword;
   5:      string hashedPassword;
   6:  
   7:      plainPassword = "P@12345566";
   8:      hashedPassword = Crypto.HashPassword(plainPassword);
   9:  
  10:      Assert.AreEqual(true, Crypto.VerifyHashedPassword(hashedPassword,plainPassword));
  11:  
  12:  }

Note: I’m using NUnit as my Unit Test Framework and Resharper as my Test Runner.

Yet better Hashing:

Even after hashing passwords you aren’t safe from hacking and hackers, hackers can use rainbow table to attack your system. The good news is you can increase the security of your hashing by adding salt, let’s see how we can do this:

Flow

Save the password looks like the same flow but this time we’ll use GenerateSalt Method in System.Web.Helpers Class to generate random salt that will be added to the password and store it to database with the hashed password.

YetBetterStoreHashingPassword

Retrieving and comparing user input password and the one stored in database is as before but you need to retrieve both the hashed password and salt from database, add salt to plain password, hash the produced string, then compare it with the hashed password that retrieved from database.

YetBetterRetreivePassword

Code:

Hash:

   1:  plainPassword = "P@12345566";
   2:  salt = Crypto.GenerateSalt();
   3:  passwordSaltCombination = plainPassword + salt;
   4:  hashedPassword = Crypto.HashPassword(passwordSaltCombination);

Compare:

   1:  Assert.AreEqual(true, Crypto.VerifyHashedPassword(hashedPassword, passwordSaltCombination));

Complete Code:

   1:  [Test]
   2:  public void test_hasing_password_with_salt()
   3:  {
   4:      string plainPassword;
   5:      string hashedPassword;
   6:      string salt;
   7:      string passwordSaltCombination;
   8:  
   9:      plainPassword = "P@12345566";
  10:      salt = Crypto.GenerateSalt();
  11:      passwordSaltCombination = plainPassword + salt;
  12:      hashedPassword = Crypto.HashPassword(passwordSaltCombination);
  13:  
  14:      Assert.AreEqual(true, Crypto.VerifyHashedPassword(hashedPassword, passwordSaltCombination));
  15:  
  16:  }

As you can see it’s simple procedure so please use it and stop saving plain password in your database.

I encourage you to read Jeff Atwood’s article You’re Probably Storing Passwords Incorrectly.