Click here to Skip to main content
15,881,172 members
Articles / Programming Languages / C#

A .NET MD5 Class Library

Rate me:
Please Sign up or sign in to vote.
1.23/5 (26 votes)
7 Mar 2006CPOL2 min read 117.4K   396   17   18
A MD5 class library for .NET supporting advanced features like random Salt values embedded in the MD5 hash.

Introduction

This article describes how to use a MD5 class library I have written for .NET. MD5 is recommended to be implemented in the following manner:

Encrypting

  1. Generate a random "Salt" value
  2. Merge the string to encrypt with the "Salt"
  3. MD5 the merged string
  4. Save the MD5 hash in one location and the Salt in another, usually a separate "Table" in your DBMS (Database Management System).

Testing

  1. Locate the saved "Salt"
  2. Merge the string and the saved "Salt"
  3. MD5 the merged string
  4. Test the new MD5 hash against the saved; if a match is found, allow usage to whatever you were protecting

Background

I chose to write this class library because all the articles and recommendation I found and were told at MSDN events recommended storing this Salt in a DBMS. I was writing an ASP.NET application where I wanted to use XML files for storage of usernames and passwords. Storing Salts in the same XML file isn't recommended, but I also didn't think it was secure storing them in any XML file "plainly". I decided to write a class that would generate the Salt, merge it with the string, encrypt the string, take the Salt, and place it in a random location in the hash, and save the hash. This allows me to store the hash in an XML file, and makes the Salt far more secure since it has to be found in the hash string first, very difficult to do. Also, since the hash string looks so similar to regular MD5 hash strings, it's hard to determine when this method is actually being used.

Using the Code

Since the code is being distributed as a class library, it is very easy to use.

Steps to using this class library:

  1. Download the package.
  2. Extract it to your hard disk.
  3. Right click References in the VS.NET IDE (Solution Explorer) and hit "Add Reference".
  4. Add code similar to that below:
  5. VB
    Imports IST.DataHash
    'Code was removed for simplicity
    
    Private Sub Button1_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles Button1.Click
        Dim MD5 As New MD5
        'Encrypts the specified string
        lblEncString.Text = MD5.Encrypt(txtEncrypt.Text)
    End Sub
    
    Private Sub Button2_Click(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles Button2.Click
    
       Dim MD5 As New MD5
    
       'Verifys the string matches the hash, returns True or False.
       lblDecString.Text = MD5.Verify(txtEncrypt.Text, lblEncString.Text)
    
    End Sub

The assembly is also Strong Name signed to allow addition to the GAC.

Source Code

VB
Imports System.Security.Cryptography
Imports System.Text
Namespace DataHash
    ''' -----------------------------------------------------------------------------
    ''' Project   : DataHash
    ''' Class     : DataHash.MD5
    ''' 
    ''' -----------------------------------------------------------------------------
    ''' <SUMMARY>
    ''' Provides advanced MD5 support for your applications
    ''' </SUMMARY>
    ''' <REMARKS>
    ''' </REMARKS>
    ''' <HISTORY>
    '''     [Frazell Thomas]    4/13/2004    Created
    ''' </HISTORY>
    ''' -----------------------------------------------------------------------------
    Public Class MD5
        Private EncStringBytes() As Byte
        Private Encoder As New UTF8Encoding
        Private MD5Hasher As New MD5CryptoServiceProvider

        ''' <SUMMARY>
        ''' Encryptes the specified string to MD5 with the Salt information embedded
        ''' </SUMMARY>
        ''' <REMARKS>
        ''' Accepts any non-array string type
        ''' </REMARKS>
        ''' <RETURNS>
        ''' Returns a string containing the MD5 HASH with embedded SALT
        ''' </RETURNS>
        ''' <EXAMPLE>
        ''' <CODE>
        ''' 'Generates a MD5 Hash for a string
        ''' Dim S as string
        ''' Dim MD5 as new IST.DataHash.MD5
        ''' s = "This is a string"
        ''' s = MD5.Encrypt(s)
        ''' </CODE>
        ''' </EXAMPLE>
        'Encrptes the string in MD5 when passed as a string
        Public Function Encrypt(ByVal EncString As String) As String
            'Variable Declarations
            Dim RanGen As New Random
            Dim RanString As String = ""
            Dim MD5String As String
            Dim RanSaltLoc As String

            'Generates a Random number of under 4 digits
            While RanString.Length <= 3
                RanString = RanString & RanGen.Next(0, 9)
            End While

            'Converts the String to bytes
            EncStringBytes = Encoder.GetBytes(EncString & RanString)

            'Generates the MD5 Byte Array
            EncStringBytes = MD5Hasher.ComputeHash(EncStringBytes)

            'Affixing Salt information into the MD5 hash
            MD5String = BitConverter.ToString(EncStringBytes)
            MD5String = MD5String.Replace("-", Nothing)

            'Finds a random location in the string to sit the salt
            RanSaltLoc = RanGen.Next(4, MD5String.Length)

            'Shoves the salt in the location
            MD5String = MD5String.Insert(RanSaltLoc, RanString)

            'Adds 0 for values under 10 so we always occupy 2 charater spaces
            If RanSaltLoc < 10 Then
                RanSaltLoc = "0" & RanSaltLoc
            End If

            'Shoves the salt location in the string at position 3
            MD5String = MD5String.Insert(3, RanSaltLoc)

            'Returns the MD5 encrypted string to the calling object
            Return MD5String
        End Function

        ''' <SUMMARY>
        ''' Verifies a string against an MD5 Hash string.
        ''' </SUMMARY>
        ''' <REMARKS>
        ''' Accepts any non-array string type
        ''' </REMARKS>
        ''' <RETURNS>
        ''' Returns <C>True</C> or <C>False</C>
        ''' </RETURNS>
        ''' <EXAMPLE>
        ''' <CODE>
        ''' 'Test a string against an MD5 Hash
        ''' Dim S as string
        ''' Dim MD5String as string
        ''' Dim MD5 as new IST.DataHash.MD5
        ''' s = "This is a string"
        ''' MD5String = MD5.Encrypt(s)
        ''' 'Prints the test results on screen
        ''' console.write(MD5.Verify(s,MD5String))
        ''' </CODE>
        ''' </EXAMPLE>
        'Verifies the String entered matches the MD5 Hash
        Public Function Verify(ByVal S As String, ByVal Hash As String) As Boolean
            'Variable Declarations
            Dim SaltAddress As Double
            Dim SaltID As String
            Dim NewHash As String

            'Finds the Salt Address and Removes the Salt Address from the string
            SaltAddress = Hash.Substring(3, 2)
            Hash = Hash.Remove(3, 2)

            'Finds the SaltID and removes it from the string
            SaltID = Hash.Substring(SaltAddress, 4)
            Hash = Hash.Remove(SaltAddress, 4)

            'Converts the string passed to us to Bytes
            EncStringBytes = Encoder.GetBytes(S & SaltID)

            'Encryptes the string passed to us with the salt
            EncStringBytes = MD5Hasher.ComputeHash(EncStringBytes)

            'Converts the Hash to a string
            NewHash = BitConverter.ToString(EncStringBytes)
            NewHash = NewHash.Replace("-", Nothing)

            'Tests the new has against the one passed to us
            If NewHash = Hash Then
                Return True
            ElseIf NewHash <> Hash Then
                Return False
            End If
        End Function

    End Class
End Namespace

Points of Interest

Various MD5 references:

History

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
I'm currently a student at Temple University in Philadelphia, PA (USA) studying Entrepreneurship. I'm also the President & CEO of Infinity Squared Technologies, Inc. a Philadelphia based technical support and solutions provider for small businesses.

Comments and Discussions

 
GeneralThat doesn't work Pin
leusha26-Jul-06 5:21
leusha26-Jul-06 5:21 
QuestionRe: That doesn't work [modified] Pin
Frazell26-Jul-06 7:26
Frazell26-Jul-06 7:26 
GeneralStill no source code! Pin
calzakk3-May-06 3:30
calzakk3-May-06 3:30 
GeneralNo Source Code !!!! Pin
alex_boyer28-Jan-06 3:08
alex_boyer28-Jan-06 3:08 
GeneralRe: No Source Code !!!! Pin
Frazell28-Jan-06 10:38
Frazell28-Jan-06 10:38 
GeneralRe: No Source Code !!!! Pin
15-Feb-06 13:59
15-Feb-06 13:59 
GeneralRe: No Source Code !!!! Pin
Frazell7-Mar-06 6:30
Frazell7-Mar-06 6:30 
GeneralRe: No Source Code !!!! Pin
stingrayweb14-Apr-06 13:15
stingrayweb14-Apr-06 13:15 
Despite no source code being posted, there's a right way and wrong way to request it.

Beginning your post with "WTF" is a pretty rude way to make a request from someone who is providing something useful for you for free.

GeneralCode Requested !! Pin
nopub17-Nov-05 22:00
nopub17-Nov-05 22:00 
GeneralSecurity through Obscurity is not Security Pin
malby19-May-04 14:05
malby19-May-04 14:05 
GeneralRe: Security through Obscurity is not Security Pin
Frazell20-May-04 0:08
Frazell20-May-04 0:08 
JokeRe: Security through Obscurity is not Security Pin
Karanig22-May-08 16:49
Karanig22-May-08 16:49 
QuestionCoDePLaNeT??? Pin
reflex@codeproject13-Apr-04 8:06
reflex@codeproject13-Apr-04 8:06 
AnswerRe: CoDePLaNeT??? Pin
Frazell13-Apr-04 12:07
Frazell13-Apr-04 12:07 
Generalnice, but Pin
martininick13-Apr-04 8:00
martininick13-Apr-04 8:00 
GeneralRe: nice, but Pin
Frazell13-Apr-04 12:08
Frazell13-Apr-04 12:08 
GeneralRe: nice, but Pin
chrisbond24-May-04 23:04
chrisbond24-May-04 23:04 
GeneralRe: nice, but Pin
Russ Harding21-Oct-05 2:36
Russ Harding21-Oct-05 2:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.