I didnt want to use Forms Authentication once and I decided to make my own password hashing just for the hell of it, here is a very simple implementation.
The goal was to save a user and the users password as a hash + a random salt string for increased security.
Also wanted to be able to generate a new password and have a hash + salt created for that new password I generated as can be seen from the following interface Crypto.cs.
Note: Yay downloaded a tool that actually Generated HTML from my code properly!! from here.
using System;
using System.Collections.Generic;
using System.Text;
namespace PassEncrypt
{
interface Crypto
{
/// <summary>
/// Gets the Hash key and Salt for a specific
/// password.
/// </summary>
/// <returns>
/// Will return a string with three elements
/// 1. Hash Key
/// 2. Salt
/// </returns>
string[] GenerateKeySalt( string plainTxtPass );
/// <summary>
/// Change the password.
///
/// </summary>
/// <returns>
/// Will return a string with three elements
/// 1. New Password
/// 2. Hash Key
/// 3. Salt
/// </returns>
string[] GenerateNewPassword();
string GetHashKey(string input);
}
}
And now to implement this interface with the Encrypt.cs class (p.s. Man I am lowing this new HTML generation from Code tool):
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
namespace PassEncrypt
{
public class Encrypt : Crypto
{
#region Generate the Hash key and salt for a given password
/// <summary>
/// Returns a salt value and a hash key to be stored
/// in the database for the given user.
/// </summary>
/// <param name=”plainTxtPass”></param>
/// <returns></returns>
public string[] GenerateKeySalt(string plainTxtPass)
{
string[] s = new string[2];
string salt = GenerateRandomSalt();
string passAndSalt = plainTxtPass + salt;
string hash = GetHashKey(passAndSalt);
s[0] = hash;
s[1] = salt;
return s;
}
#endregion
#region Generate a new password
/// <summary>
/// Generates a new random password and returns a string array with:
/// 1. new password
/// 2. hash key
/// 3. salt value
/// </summary>
/// <returns></returns>
public string[] GenerateNewPassword()
{
string[] s = new string[3];
RandomPassword randPassGenerator = new RandomPassword();
string newPass = randPassGenerator.GetPassword();
string salt = GenerateRandomSalt();
string passAndSalt = newPass + salt;
string hash = GetHashKey(passAndSalt);
s[0] = newPass;
s[1] = hash;
s[2] = salt;
return s;
}
#endregion
#region Generate random salt
/// <summary>
/// Generates a cryptographically strong salt string
/// </summary>
/// <returns></returns>
public string GenerateRandomSalt()
{
RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
byte[] saltInBytes = new byte[5];
crypto.GetBytes(saltInBytes);
return Convert.ToBase64String(saltInBytes);
}
#endregion
#region Get the hash key for a given string
public string GetHashKey(string input)
{
byte[] tmpSource;
byte[] tmpHash;
//Convert input to a Byte Array (needed for hash function)
tmpSource = ASCIIEncoding.ASCII.GetBytes(input);
//Compute hash based on source data.
tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
return Convert.ToBase64String(tmpHash);
}
#endregion
}
}
The following class (RandomPassword.cs) contains my Random password generator. You may want to modify it according to the type of password you would like to generate:
using System;
using System.Collections.Generic;
using System.Text;
namespace PassEncrypt
{
class RandomPassword
{
private int RandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
/// <summary>
/// Generates a random string with the given length
/// </summary>
/// <param name=”size”>Size of the string</param>
/// <param name=”lowerCase”>If true, generate lowercase string</param>
/// <returns>Random string</returns>
private string RandomString(int size, bool lowerCase)
{
StringBuilder builder = new StringBuilder();
Random random = new Random();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
if (lowerCase)
return builder.ToString().ToLower();
return builder.ToString();
}
public string GetPassword()
{
StringBuilder builder = new StringBuilder();
builder.Append(RandomString(4, true));
builder.Append(RandomNumber(1000, 9999));
return builder.ToString();
}
}
}
Thats all there is to it. I just made this is a class library project names PassEncrypt.

Just reference PassEncrypt and:
For a new user send their password in and get an array containing the [hash,salt], store these somewhere and associate them with the username:
#region Get Hashed password
public bool GetHashPassword(string username, string password)
{
Encrypt crypt = new Encrypt();
string user = username;
string pwd = password;
string salt = “”;
salt = dataService.GetUserSalt(user);
if (salt != “”)
{
string passHash = dataService.GetUserHash(user);
string resultHash = crypt.GetHashKey(pwd + salt);
if (passHash == resultHash)
{ //Password Correct
return true;
}
else
{
return false;
}
}
else
return false;
}
#endregion