Walkthrough: ASP.NET PasswordHasher Class


I did that lately and like to share that with you:

1. Create a new subdirectory in the App_Code directory of BalloonShop called SecurityLib.
2. Add a new class file called PasswordHasher.cs with code as follows:

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
namespace SecurityLib
{
public static class PasswordHasher
{
private static SHA1Managed hasher = new SHA1Managed();
public static string Hash(string password)
{

// convert password to byte array
byte[] passwordBytes =
System.Text.ASCIIEncoding.ASCII.GetBytes(password);
// generate hash from byte array of password
byte[] passwordHash = hasher.ComputeHash(passwordBytes);
// convert hash to string
return Convert.ToBase64String(passwordHash , 0,
passwordHash.Length);
     }
   }
}

3. Add a new web page to the root of your web site called SecurityLibTester.aspx, using
the usual options for having code in an external file and selecting the default Master Page (if you have one).
4. Add the following code to SecurityLibTester.aspx:

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master"
AutoEventWireup="true" CodeFile="SecurityLibTester.aspx.cs"
Inherits="SecurityLibTester" Title="SecurityLib Test Page" %>
<asp:Content ID="Content1"
ContentPlaceHolderID="contentPlaceHolder" runat="Server">
Enter your password:<br />
<asp:TextBox ID="pwdBox1" runat="server" />
<br />
Enter your password again:<br />
<asp:TextBox ID="pwdBox2" runat="server" />
<br />
<asp:Button ID="processButton" runat="server" Text="Process"
OnClick="processButton_Click" />
<br />
<asp:Label ID="result" runat="server" />
</asp:Content>

5. Modify SecurityLibTester.aspx.cs as follows:

using System;
...
using System.Text;
using SecurityLib;
public partial class SecurityLibTester : System.Web.UI.Page
{
...
protected void processButton_Click(object sender, EventArgs e)
{
string hash1 = PasswordHasher.Hash(pwdBox1.Text);
string hash2 = PasswordHasher.Hash(pwdBox2.Text);
StringBuilder sb = new StringBuilder();
sb.Append("The hash of the first password is: ");
sb.Append(hash1);
sb.Append("<br />The hash of the second password is: ");
sb.Append(hash2);
if (hash1 == hash2)
{
sb.Append("<br />The passwords match! Welcome!");
}
else
{
sb.Append("<br />Password invalid. "
+ "Armed guards are on their way.");
}
result.Text = sb.ToString();
}
}

6. Browse to SecurityLibTester.aspx, enter two passwords, and click Process. Voila, check if it matches.

How It Works: Implementing the PasswordHasher Class

The code in the PasswordHasher class follows the steps that were discussed earlier. First, you use the utility
function System.Text.ASCIIEncoding.ASCII.GetBytes to convert the password string into a byte array:

// convert password to byte array
byte[]passwordBytes =
System.Text.ASCIIEncoding.ASCII.GetBytes(password);
Next, you use the private shared member hasher, an instance of SHA1Managed, to generate a hash byte array:
// generate hash from byte array of password
byte[] passwordHash = hasher.ComputeHash(passwordBytes);

Finally, you convert the hash back into a string by using the utility function Convert.ToBase64String and return
the result:

// convert hash to string
return Convert.ToBase64String(passwordHash , 0,
passwordHash.Length);

All the hash algorithm classes in the .NET Framework use this ComputeHash method to get a hash from an input
array of bytes. To increase the size of the hash, you can replace the hasher with another one of these, for example:

public static class PasswordHasher
{
private static SHA512Managed hasher = new SHA512Managed();
...
}

This change would result in a 512-bit hash, which is probably a bit excessive in this sort of application!
The client page, SecurityLibTest.aspx, hashes two passwords and compares the result. The code is basic
enough to ignore for now, but it’s important to note that the generated hashes vary a great deal for even simple
changes to the input data, even just changes of case—one of the defining features of good hash generation.

That’s it, hope you find it useful!

1 comment so far ↓

#1 Tim Carpenter on 04.19.06 at 3:37 pm

Great Article, thanks Andreas!

Leave a Comment