# C# : Hash Encryption Example



## Kreij (Jun 7, 2008)

So ... you want users to have to log into your application, supplying a user name and password.
When you create the user you don't want to just stuff the unprotected password into the database.
(well you might, but that is generally not such a great idea)

An easy way to make the passwords secure in the database is to run them through a hash function to encrypt the data before you insert them.
A hash function takes it's input and runs it through an algorithm that results in a fixed-size value no matter what the length of the input, based on which algorithm you are using.
For this example, we will be using a MD5 hash which is 128 bit encryption, and will be returning the result as a hexadecimal string.
The nice thing about hashes is that a small change in the input will results in large and unexpected changes in the resulting hash, making them very secure. The odds of two different inputs resulting in the same hash is astronomically small.

Basically what you do is send in the password string and output the encrypted string.
(I am not including any database stuff here for brevity)

In C# you will need to include a few namespaces

```
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;  // This is for password validation
using System.Security.Cryptography;  // This is where the hash functions reside
```

Here is the code that converts the password to a hexadecimal string
I am using public methods as I have this written into a separate class so it can be called from any other class

```
public string GeneratePasswordHash(string thisPassword)
{
    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
    byte[] tmpSource;
    byte[] tmpHash
    
    tmpSource = ASCIIEncoding.ASCII.GetBytes(thisPassword); // Turn password into byte array
    tmpHash = md5.ComputeHash(tmpSource);

    StringBuilder sOuput = new StringBuilder(tmpHash.Length);
    for (int i = 0; i < tmpHash.Lenth; i++)
    {
        sOutput.Append(tmpHash[i].ToString(“X2”));  // X2 formats to hexadecimal
    }
    return sOutput.ToString();
}
```

You can now place the output from GeneratePasswordHash() into a string field in your database.

But wait, you say, there is no way to decrypt a hash to get the original password back!

Correct. That is why we need a simple function to encrypt what the user types in and compare it to the hash in the database. Identical input will always produce identical hashes.


```
public Boolean VerifyHashPassword(string thisPassword, string thisHash)
{
    Boolean IsValid = false;
    string tmpHash = GeneratePasswordHash(thisPassword); // Call the routine on user input
    if (tmpHash == thisHash) IsValid = true;  // Compare to previously generated hash
    return IsValid;
}
```

If the function returns “true”, then the user typed in the correct password.

I also added a couple of methods that you can use to validate and sanitize the passwords.
This is a good idea for any database input to keep someone from sending in SQL commands through the input that could wreak havoc or compromise your database.
Depending on what you would consider a valid password would determine what regular expression you use in the following code.


```
public Boolean isValidPassword(string thisPassword)
{
    string newPassword = sanitizeInput(thisPassword);
    Regex regX = new Regex(@"^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{5,15)");
    return regX.Match(newPassword).Success;
}
```

And, of course, a method to sanitize the input. This method simply removes any invalid characters from the input string. Again, you would be the one who determines what is not valid for the input.

```
public string sanitizeInput(string thisInput)
{
    Regex regX = new Regex(@"([<>""'%;()&])");
    return regX.Replace(thisInput, "");
}
```

On a side note, the hash functions will also take input from a stream. This means that you can stream in the contents of a whole file to get a hash. This is how your basic MD5 programs work for validating file downloads.

Thanks for reading, and have fun hashing!!


----------



## magibeg (Jun 7, 2008)

This was very useful. Thanks


----------



## Kreij (Jun 7, 2008)

I would also like to mention that Microsoft has included many, many hashing algorithm classes in the Cryptography namespace, so you can choose the one that best fits the type of hashing that you wish to perform.


----------



## Kreij (Jun 7, 2008)

Ooops ... one other thing that I forgot to mention was that if you use hash encryption to store passwords in a database, and the user forgets their password, there is no way to retrieve it. You will have to generate a new password (and hash) for that user.


----------



## Cold Storm (Jun 7, 2008)

I do have to say Kreij, that I did learn something from it. Thanks for lending us your knowledge on C#


----------



## Kreij (Jun 7, 2008)

Cold Storm said:


> I do have to say Kreij, that I did learn something from it. Thanks for lending us your knowledge on C#



If we are not willing to freely share the knowledge that we have attained, who will teach the next generation?

I do not claim to know a lot about anything, but it is an honor to be able to share what I have learned with anyone who takes a moment to listen.


----------



## Cold Storm (Jun 7, 2008)

Kreij said:


> If we are not willing to freely share the knowledge that we have attained, who will teach the next generation?
> 
> I do not claim to know a lot about anything, but it is an honor to be able to share what I have learned with anyone who takes a monent to listen.



That is true. And without places like this, we won't be able to learn the stuff that others will just say "go look for it"


----------



## Solaris17 (Jun 7, 2008)

this is amazing hey kreij know anything bout C++?


----------



## calvary1980 (Jun 7, 2008)

I do. and I can show you how to decrypt MD5 

good work Kreij.

- Christine


----------



## Solaris17 (Jun 7, 2008)

calvary1980 said:


> I do. and I can show you how to decrypt MD5
> 
> good work Kreij.
> 
> - Christine



rry? this is quite intresting.


----------



## Kreij (Jun 7, 2008)

calvary1980 said:


> I do. and I can show you how to decrypt MD5
> 
> good work Kreij.
> 
> - Christine



Tsk, Tsk Christine. You know there are limitations on that.


----------



## Kreij (Jun 8, 2008)

Solaris17 said:


> this is amazing hey kreij know anything bout C++?



Yeah, Sol, I know C++ and several other languages.
I just like C# better.
It (for the most part) enforces stricter rules on "safe" code, and the syntax is clearer and easier to read (as you can see if you compare some of the posting with both languages).

Many people said that C# ran slower than C++ (especially with games) due to the fact that it is a managed (everything in a wrapper class) language, but with the compiler optimizations that MS has done, it's pretty darn close these days.


----------

