More on SHA1, MD5 and other hash algorithms with .Net

by Jason Haley 27. February 2005 16:17

I read Robert Hurlbut's entry, quite a bit of Rotor's strongname.h and strongname.cpp files, looked at some metadata items in Inside Microsoft .Net IL Assembler, read through some of Chapter 3 in Applied Microsoft .Net Framework, CLI Partition II: Metadata Definition and Semantics, and googled a lot of stuff this morning on .Net (CLI)'s metadata model and verification (I actually bookmarked a lot of stuff I am going to read through this week).  Also found a good book on metadata at http://vijaymukhi.com/documents/books/metadata/.  All in all I would Richter explained what I was looking for the best - more on this later in the week. 

SHA1 is the default hashing algorithm for assemblies, but you can change it to MD5.  Unfortunately that is it.  In order to change this setting, you need to add an assembly attribute AssemblyAlgorithmIdAttribute, the hash algorithm is determined by the value of AssemblyHashAlgorithm Enumeration that you use.  The code would look like this for MD5:

    1 using System;

    2 using System.Reflection;

    3 using System.Configuration.Assemblies;

    4  

    5 [assembly: AssemblyDelaySign(false)]

    6 [assembly: AssemblyKeyFile(@"../../testkey.snk")]

    7 [assembly: AssemblyAlgorithmId(AssemblyHashAlgorithm.MD5)]

 

In order to use the AsssemblyHashAlgorithm enumeration you will need to add a using or imports statement to System.Configuration.Assemblies.

On the web side of things there is the <machineKey> element of the machine.config that can be configured to use either SHA1, MD5 or 3DES when you want too protect against ViewState tampering... just read this article on Codinghorror first

In the process of finding out exactly what happens when you Strong name an assembly to protect against tampering of an assembly, I came up with the following method to understand how .net comes up with the public key token:

   38         public byte[] GetPublicKeyTokenSHA1(byte[] publicKey)

   39         {

   40             SHA1Managed sha1 = new SHA1Managed();

   41             byte[] sha1PublicKeyHash = sha1.ComputeHash(publicKey, 0, publicKey.Length);

   42        

   43             byte[] _sha1PublicKeyToken = new byte[8];

   44             for (int i = 0; i < 8; i++)

   45             {

   46                 _sha1PublicKeyToken[8 - (i + 1)] = sha1PublicKeyHash[i + (sha1PublicKeyHash.Length - 8)];

   47             }

   48            

   49             return _sha1PublicKeyToken;

   50         }

This method will generate the public key token (only 8 bytes) from the public key, that will be used in the gac directory and other places where the full key is too long.

Comments (0) | Post RSSRSS comment feed |

Categories:
Tags:

Comments are closed