Click here to Skip to main content
15,882,152 members
Articles / Programming Languages / C#
Tip/Trick

Key with Salt Hashing Provider Library

Rate me:
Please Sign up or sign in to vote.
4.71/5 (4 votes)
17 Jan 2018CPOL4 min read 9.3K   168   9   1
This article describes a simple class library which provides a key with salt hashing mechanism.

Introduction

This article describes a sample class library which you can use to generate salts and encrypted passwords. Taken together, these can be used to perform such functions such as verifying a user's entered password against that which is stored to see if the user has entered the correct password. This class library does not attempt to provide a new encryption algorithm but rather aggregates existing encryption functionality together for ease of use. The assumption is that your application users salted passwords were recorded in an encrypted state in a data store such as a database. Also assumed is that those with strong security needs will supplement encryption with multi-factor authentication.

Background

The Problem

Have you ever worked in an organization which struggled with unnecessary variation in its code base, meaning that there exists multiple different coding styles to satisfy the exact same results, making code management frustrating? Specifically, have you ever had multiple applications in which each had a different security model even though the security needs for each application were the same?

The Solution

This article describes a simple class library that can be used uniformly across your projects to help in the effort to cut down on unnecessary code variation. Specifically, the class library provides key hashing with salt capability. For my purposes, I had "wrapped" a web API around this class library, so that all applications would consistently communicate with the class library methods through the web API, but of course, you only need do this if it makes sense in your situation.

Tech Details

The source code exists within a Visual Studio solution named HashKeyProvider and when compiled, provides two class library files as DLLs, HashGenerator and SaltGenerator. I used Visual Studio Professional 2017 with the .NET Framework 4.6.1 for each of the projects within the solution. I also used MS Test for the unit tests (existing within its own unit test project) which provides for a nice way of demonstrating the code, as well as, testing it. At the time of this writing, I'm using the SHA512 algorithm for encrypting passwords.

A Little Bit of Theory

If you'll recall, it is not a good security practice to store user passwords without first encrypting them, meaning that passwords should be stored in an encrypted state. The encryption function should be deterministic, meaning that for the same entered password, their encrypted values should match. This provides a means of verifying a user's currently entered password against a previously stored one in an encrypted state, the stored one usually existing in a database. Even if the stored encrypted value is hacked, the hacker will not know what the underlying password is from which the encrypted version came from. This statement is true assuming that the encryption function is non-invertible, meaning that the input value of the function (the domain) cannot be inferred from the output value of the function (the range).

For added security, it is best to "salt" a password prior to encrypting it. Our assumption is that every generated salt should be different, non-deterministic, and use a random number generator to achieve this goal.

Using the Code

The Visual Studio HashKeyProvider solution is split into three projects. The core implementation of the class methods are contained within a project named Core and contains their HashGenerator and SaltGenerator classes. The interfaces are stored within a project named Core.Interfaces, and the unit tests are stored within a test project named UnitTestProject.

Why don't we begin our explanation of the code through following a common use case scenario?

For instance, say that we have a new application user for which we want to store their encrypted password. Prior to encrypting their password, we'll want to generate a random salt. The CreateRandomSalt method accomplishes this and returns the generated salt to its caller.

C#
public class SaltGenerator : ISaltGenerator
{
	public string CreateRandomSalt()
	{
		byte[] saltBytes = new byte[64];

		var rng = RandomNumberGenerator.Create();
		rng.GetNonZeroBytes(saltBytes);
		var saltText = BitConverter.ToString(saltBytes);

		return saltText;
	}
}

Now that we have a salt, we can combine it with the password to create an encrypted hashed key of it.

This can be accomplished through calling the CreateHashedKey method of the below shown class HashGenerator.

C#
public class HashGenerator : IHashGenerator
{
	public string CreateHashedKey(string pswd, string salt)
	{
		byte[] pswdBytes = Encoding.UTF8.GetBytes(pswd);
		byte[] saltBytes = Encoding.UTF8.GetBytes(salt);
		byte[] pswdWithSaltBytes = new byte[pswdBytes.Length + saltBytes.Length];

		for (int i = 0; i < pswdBytes.Length; i++)
		{
			pswdWithSaltBytes[i] = pswdBytes[i];
		}

		for (int i = 0; i < saltBytes.Length; i++)
		{
			pswdWithSaltBytes[pswdBytes.Length + i] = saltBytes[i];
		}
		
		var cryptoProvider = SHA512.Create();
		byte[] hashedBytes = cryptoProvider.ComputeHash(pswdWithSaltBytes);

		var hashedText = BitConverter.ToString(hashedBytes);

		return hashedText;
	}
}

Points of Interest

You'll notice that there is no code as part of this library which actually submits or retrieves a password or salt. That is the responsibility of other code (separation of concerns), as the purpose of this class library is to merely generate salts and encrypt passwords with their salts. Neither have I mentioned how the salt and unencrypted password are sent to the methods in this code library, such as whether communication between the caller and these methods are accomplished using TLS, etc. In my usage, this class library is one piece of a larger security model which may be different than your needs, so I've left these details up to you to fill in.

Regardless, I do believe that it is helpful to have code which performs salt and hashed key creation separate from code which retrieves salts and passwords and transport level details to the larger security model.

License

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


Written By
Software Developer
United States United States
I am a web, software, and database developer having primarily a .Net and SQL Server concentration. I am also interested in leveraging other technologies where they are best utilized.

Comments and Discussions

 
PraiseGood Pin
DalalV18-Jan-18 1:53
DalalV18-Jan-18 1:53 

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.