Every application uses username and password to provide security to the systems. The way an application handles the storage of password defines the level of security provided by the application.
The password should not be stored in the database as a string. Rather, it should be converted to an unrecognizable value that is unique for any defined password. This value is called a hash. Hashing algorithms are defined so that any string that is hashed to a unique value will always be hashed to that unique value.
When an end user defines a password, the password should be hashed to a unique value, and that unique value should be stored in the database. When the end user logs in with the password, the password can be hashed again using the same algorithm. The resulting value can be compared with the hashed value stored in the database to validate the login.
Hashed values cannot be “unhashed,” so there is no way to get the original password back from the hashed value. This provides an additional level of security, because if someone obtains hashed passwords from the database, they cannot be converted back to the original passwords. A side effect of this is that if an end user forgets the password, a new password would need to be assigned.
The System.Security.Cryptography library in the .NET Framework provides a set of classes that assist with hashing. Two primary hashing schemes are provided in this library:
- MD5: The Message Digest 5 (MD5) hash digest uses an MD5 algorithm to hash a value, such as an end user password. This algorithm provides better performance than SHA1.
- SHA1: The Secure Hash Algorithm-1 (SHA1) hash digest uses a SHA1 algorithm to hash a value, such as an end user password. This algorithm provides better security than MD5.
A password such as “password” will have a hash that looks something like W6ph5Mm5Pz8GgiULbPgzG37mj9g=.
The following code uses the SHA1 algorithm to hash a password:
using System.Security.Cryptography;
public static String ComputeHash(string textToHash)
{
SHA1CryptoServiceProvider SHA1 = new SHA1CryptoServiceProvider();
byte[] byteValue = System.Text.Encoding.UTF8.GetBytes(textToHash);
byte[] byteHash = SHA1.ComputeHash(byteValue);
SHA1.Clear();
return Convert.ToBase64String(byteHash);
}
You can put this code in a utility component and reuse it in every application that needs to store a password or other secure information.
But hashing a password does not protect the application from a dictionary attack. For further security, salt the password as well.