ÜberUtils - Part 1 : Cryptography
ÜberUtils Series posts so far :
- Part 1 : Cryptography - Hashing
-
Part 2 : Cryptography (Continued)
- Encryption
- Part 3 : Strings
- Part 4 : Collections
If you read my
previous post, you would know that it is my time to give back to the
community. So where should you start when creating the
ULTIMATE REUSABLE UTILS CLASS LIBRARY? (from now on
called
ÜberUtils)? Good question, and thats the reason why its taken me a
while to start this series, cause I had to start it at
exactly the right point. I thought back to the first utils
class I wrote back in 2003 in .NET 1.1. It was a
cryptography class that wrapped existing functionality that
exists in the system.security.cryptography namespace.
So I figure thats a good place to start again. But
first I wanna note a few things :
-
This code will be written for .NET 3.5 framework (this is
to take advantage of the newer features)
- I will be using VS2008 beta 2 which, which at this point in time (Oct 2007), you can download for free. (I want to utilise some of the new features available e.g. Unit Testing)
-
The namespaces I use will be as simple and generic as
possible, meaning that it will be simple to incorporate
into any number of companies / projects / systems /
architectures etc. I hate having weird long namespaces
when I use other developers libraries. I would prefer a
namespace like "Utils" rather than "BradVin.Core.Utils".
Wouldnt you agree? (I was also thinking about using
"System.Utils")
- The project files and code can be downloaded from codeplex at the ÜberUtils project page.
-
Code license :
public domain. This means that all the code in this series is
absolutely free, and by definition : the code
may be freely reproduced, distributed, transmitted,
used, modified, built upon, or otherwise exploited by
anyone for any purpose, commercial or non-commercial,
and in any way, including by methods that have not yet
been invented or conceived. So rip it to pieces, pull out what you like - I DONT
CARE! My only stipulation is this :
IF YOU ADD SOMETHING USEFUL PLEASE SHARE IT WITH
US!!!!! (you can do this by commenting on this blog or on
discussing it at code plex)
I'm gonna start with a Hashing class which is
extremely simple to use. This class makes it easy to hash a
byte array or a string e.g.
string strHash = Hashing.Hash("test");
You can also use different hashing algorithms e.g.
string strHash = Hashing.Hash("test", Hashing.HashingTypes.SHA512);
Internally, the different hashing algorithm classes used are : SHA1CryptoServiceProvider, SHA256Managed, SHA384Managed, SHA512Managed and the default MD5CryptoServiceProvider.
Very simple isn't it?. Here is the class diagram :
If you have a look at the code, you would have noticed some
strange new methods on both string and byte array. This is
using a new .NET 3.5 feature called
extension methods. If you've not heard of it yet, the
best explanation is by ScottGu
here. Infinities Loop also talks about it
here
and ScottGu again
here
. So let's see how I implement my extension methods. Check
this code out :
private string ComputeHash(string inputText)You'll see a string has a new method called ToByteArray. Also note that the ComputeHash method returns a byte array, and this means that a byte array now has a new method too : ToHexString. Here is the code for these 2 extension methods :
{
//convert output byte array to a string
return ComputeHash(inputText.ToByteArray()).ToHexString().ToUpper();
}
namespace Utils.Extensions
{
public static class ByteArrays
{
public static string ToHexString(this byte[] data)
{
StringBuilder sb = new StringBuilder(data.Length * 2);
foreach (byte b in data)
{
sb.AppendFormat("{0:x2}", b);
}
return sb.ToString();
}
public static byte[] ToByteArray(this string str)
{
return ASCIIEncoding.ASCII.GetBytes(str);
}
}
}
Now all I had to do to use these methods was add a using at the top of my class :
using Utils.Extensions;
But I didn't want to just stop here. I've had a scenario in the past when I needed to compute a MD5 hash of a string. I also found this blog post on the subject and decided I can now use extension methods to add this functionality to every string. So heres the code :
namespace Utils.Extensions
{
public static class Cryptography
{
public static string GetMD5HashCode(this string str)
{
return Utils.Cryptography.Hashing.Hash(str);
}
}
}
So now I can use it on any string e.g.
string actual = "test".GetMD5HashCode();So thats the Hashing class. This post ended up a lot longer than I expected, so in my next post Im going to add an encryption class. Please check out the code (Download here or get it from my CodePlex project page). Included in the source are unit tests that check the hashing is doing its job correctly. (I used the System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile method to make sure the tests are valid and double checked the results against other non-C# hashing algorithms e.g. http://pajhome.org.uk/crypt/md5/ )