The System.Security.Cryptography namespace contains several implementations of Hash algorithms. Three kinds of algorithms are available: MD5, SHA in different 'flavor' (SHA-1, SHA-256, SHA-384 and SHA-512) and RIPEMD-160. MD5 is popular but weak. SHA is stronger and widely used. RIPE Message Digest is less well knows. Probably because RIPEMD was designed by a group of European academic researchers, while SHA was designed by the NSA.
A Hash algorithm creates a fixed length hash value, also called the message digest, from a plain text message. The message himself is not encrypted and this is a one way process. In other words, you can’t recreate the original message from the message digest. Those algorithms can be used to tamper a message or to detect changes. The message can't be changed and the message digest is the proof that it has not been altered. Because if you change just a few bits, the resulting message digest will be completely different. Although it is possible than two different messages produce the same message digest, the probability of a collision is very low. This is why a message digest is sometime used as a key in a hash table.
Do not confuse the message digest with the hash value used in a HashTable class! The first is a byte array of a fixed size generated by a cryptographic Hash algorithm; while the second is an integer computed by a mathematical function. In some cases, this function can be simple as returning a record identifier. If you are curious, look at the GetHashCode() method of the String class using Reflector. You will discover how a hash value can be computed from a string.
Suppose you are competitor in a contest about computer history. One question is: "Who is the inventor of the DEK Hash Function?" You call me for the answer but I want to be fair with other competitors and I tell you: "I know his name and I can prove it, it's: 59FFB19672028402F240543166FED84A30BE3424". With this SHA-1 message digest, you will be able to verify my answer, when I will give it to you. Do you know the name of this person?
Another common use case of a Hash algorithm is to generate a cryptographic key from a weak password. This allows you to have a more secure scheme when encrypting a message with a password using a symmetric algorithm. Also instead to store an encrypted password in a database, you can use a Hash algorithm to create a message digest and store it into the database. To authenticate a user, you just have to create a message digest with the submitted password and compare it with the stored one.
The main problem with Hash algorithms is than the same message produces always the same message digest thus they are exposed to dictionary attacks. Some articles on the Internet show you how to 'salt' your message. This can be done by a function like: Hash(message + Hash(salt)). Instead, you should use the more secure keyed hash algorithms.
HMAC (Hash-based Message Authentication Code) algorithms inherit from the hash algorithms combined with a secret key. The .Net framework implements seven of them: HMACMD5, HMACRIPEMD-160, HMACSHA1, HMACSHA256, HMACSHA384, HMACSHA512 and HMACTripleDES. They are used to control both data integrity and authentication of a message. Of course the secret key must be shared to be able to validate the message.
Imagine you have a B2B on line store. The user account could be used by several people to authenticate the company and allow access to the company’s orders and other data. However, you don't want than anyone can submit an order! You could then use a keyed hash algorithm with a secret key shared by a few people allowed to submit an order. To avoid a brute force attack against a weak secret key, you can apply a Hash algorithm to a passphrase and use the message digest as the secret key. Moreover, a passphrase like 'My Secret Key' is simpler to memorize by a human than 04F13208B4A051...
I'd write briefly on asymmetric algorithms, and then I give you more details about symmetric algorithms in the new part. Stay tuned!