: C# 2008 Programmer

Salted Hash

Salted Hash

With hashing, you simply store the hash value of a user's password in the database. However, if two users use identical passwords, the hash values for these two passwords will be also identical. Imagine a hacker seeing that the two hash values are identical; it would not be hard for him to guess that the two passwords must be the same. For example, users often like to use their own names or birth dates or common words found in the dictionary as passwords. So, hackers often like to use dictionary attacks to correctly guess users' passwords. To reduce the chance of dictionary attacks, you can add a "salt" to the hashing process so that no two identical passwords can generate the same hash values. For instance, instead of hashing a user's password, you hash his password together with his other information, such as email address, birth date, last name, first name, and so on. The idea is to ensure that each user will have a unique password hash value. While the idea of using the user's information as a salt for the hashing process sounds good, it is quite easy for hackers to guess. A better approach is to randomly generate a number to be used as the salt and then hash it together with the user's password.

The following function, Salted_Hashing_SHA1(), generates a random number using the RNGCryptoServiceProvider class, which returns a list of randomly generated bytes (the salt). It then combines the salt with the original password and performs a hash on it.

static void Salted_Hashing_SHA1() {
//---Random Number Generator---
byte[] salt = new byte[8];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(salt);
//---ask the user to enter a password---
Console.Write("Please enter a password: ");
string password = Console.ReadLine();
//---add the salt to the password---
password += ASCIIEncoding.ASCII.GetString(salt);
//---hash the password---
byte[] data = ASCIIEncoding.ASCII.GetBytes(password);
SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
byte[] passwordHash;
passwordHash = sha.ComputeHash(data);
//---ask the user to enter the same password again---
Console.Write("Please enter password again: ");
password = Console.ReadLine();
Console.WriteLine(ASCIIEncoding.ASCII.GetString(salt));
//---adding the salt to the second password---
password += ASCIIEncoding.ASCII.GetString(salt);
//---hash the second password and compare it with the first---
data = ASCIIEncoding.ASCII.GetBytes(password);
if (ASCIIEncoding.ASCII.GetString(passwordHash) ==
ASCIIEncoding.ASCII.GetString(sha.ComputeHash(data)))
Console.WriteLine("Same password");
else Console.WriteLine("Incorrect password");
}

If you use salted hash for storing passwords, the salt used for each password should be stored separately from the main hash database so that hackers do not have a chance to obtain it easily.


: 1.292. /Cache: 3 / 1