How to do it...

  1. The easiest way is to create a console application and then add a new class library by right-clicking on your solution, and selecting Add and then New Project from the context menu.
  1. From the Add New Project dialog screen, select Class Library from the installed templates and call your class Chapter15.
  1. Your new class library will be added to your solution with a default name of Class1.cs, which we renamed Recipes.cs in order to distinguish the code properly. You can, however, rename your class whatever you like if that makes more sense to you.
  2. To rename your class, simply click on the class name in the Solution Explorer and select Rename from the context menu.
  1. Visual Studio will ask you to confirm a rename of all references to the code element Class1 in the project. Just click on Yes.
  1. The following class is added to your Chapter15 library project:
        namespace Chapter15 
{
public static class Recipes
{

}
}
  1. Add the following using statement to your class:
        using System.Security.Cryptography;
  1. Next, you need to add two properties to the class. These properties will store the salt and the hash. Usually you will write these values to the database along with the username, but, for the purposes of this recipe, we will simply add them to the static properties. Also add two methods to the class called RegisterUser() and ValidateLogin(). Both methods take as parameters the username and password variables:
        public static class Recipes 
{
public static string saltValue { get; set; }
public static string hashValue { get; set; }

public static void RegisterUser(string password, string
username)
{

}

public static void ValidateLogin(string password,
string username)
{

}
}
  1. Starting with the RegisterUser() method, here we do a number of things. To list the steps in the method:

1. We generate a truly random, cryptographically strong salt value using RNGCryptoServiceProvider.

2. Add the salt to the password and hash the salted password using SHA256.

It doesn't matter if you add the salt before or after the password. Just remember to be consistent each time you do it.

3. Store the salt value and the hash value along with the username in the database.

In order to cut down on code, I have not actually added code to write the hash and salt values to the database. I simply added them to the properties created earlier. In a real-world situation, you would always write these to the database.

This is a very secure way to handle user passwords in your application:

        public static void RegisterUser(string password, string  username) 
{
// Create a truly random salt using RNGCryptoServiceProvider.
RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();
byte[] salt = new byte[32];
csprng.GetBytes(salt);

// Get the salt value
saltValue = Convert.ToBase64String(salt);
// Salt the password
byte[] saltedPassword = Encoding.UTF8.GetBytes(
saltValue + password);

// Hash the salted password using SHA256
SHA256Managed hashstring = new SHA256Managed();
byte[] hash = hashstring.ComputeHash(saltedPassword);

// Save both the salt and the hash in the user's database record.
saltValue = Convert.ToBase64String(salt);
hashValue = Convert.ToBase64String(hash);
}
  1. The next method we need to create is the ValidateLogin() method. Here, we take the username and validate that first. If the user entered the username incorrectly, do not tell them so. This would alert someone trying to compromise the system that they have the wrong username and that as soon as they get a wrong password notification, they know that the username is correct. The steps in this method are as follows:
    1. Get the salt and hash values for the entered username from the database.
    2. Salt the password the user entered at the login screen with the salt read from the database.
    3. Hash the salted password using the same hashing algorithm when the user registered.
    4. Compare the hash value read from the database to the hash value generated in the method. If the two hashes match, then the password is correctly entered and the user validated.

Note that we never decrypt the password from the database. If you have code decrypting user passwords and matching the password entered, you need to reconsider and rewrite your password logic. A system should never be able to decrypt user passwords.

        public static void ValidateLogin(string password, string username) 
{
// Read the user's salt value from the database
string saltValueFromDB = saltValue;

// Read the user's hash value from the database
string hashValueFromDB = hashValue;

byte[] saltedPassword = Encoding.UTF8.GetBytes(
saltValueFromDB + password);

// Hash the salted password using SHA256
SHA256Managed hashstring = new SHA256Managed();
byte[] hash = hashstring.ComputeHash(saltedPassword);

string hashToCompare = Convert.ToBase64String(hash);

if (hashValueFromDB.Equals(hashToCompare))
Console.WriteLine("User Validated.");
else
Console.WriteLine("Login credentials incorrect. User not
validated.");
}
  1. To test the code, add a reference to the Chapter15 class in your CodeSamples project.
  2. Because we created a static class, you can add the new using static to your Program.cs file:
        using static Chapter15.Recipes;
  1. Test the code by calling the RegisterUser() method and pass it the username and password variable. After that, call the ValidateLogin() method and see whether the password matches the hash. This would obviously not happen at the same time in a real production system:
        string username = "dirk.strauss"; 
string password = "^tj_Y4$g1!8LkD";
RegisterUser(password, username);

ValidateLogin(password, username);
Console.ReadLine();
  1. When you debug the code, you will see the user has been validated:
  1. Lastly, modify the code slightly and set the password variable to something else. This will mimic a user entering an incorrect password:
        string username = "dirk.strauss"; 
string password = "^tj_Y4$g1!8LkD";
RegisterUser(password, username);

password = "WrongPassword";
ValidateLogin(password, username);
Console.ReadLine();
  1. When you debug the application, you will see that the user is not validated:
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.226.121