In cryptography, a salt is random data that is used as an additional input to a one-way function that “hashes” data, a password or passphrase. Salts are closely related to the concept of nonce. The primary function of salts is to defend against dictionary attacks or against its hashed equivalent, a pre-computed rainbow table attack.
This can be visually demonstrated as:
Cool, how do we do this in code?
Consider the following username and password:
var email = "email@example.com"; var password = "qwerty";
The password value needs to be hashed and then persisted to the database.
1. Create the salt by getting the byte array values of the email, the assumption would be that an email address is unique.
var salt = Encoding.ASCII.GetBytes(username);
2. Create a byte array of the password and concatenate the two into one byte array
var _value = Encoding.UTF8.GetBytes(password); var saltedValue = _value.Concat(salt).ToArray();
3. Create a MD5 hash from the ‘salted value’
// need MD5 to calculate the hash byte hash = ((HashAlgorithm)CryptoConfig.CreateFromName("MD5")).ComputeHash(saltedValue);
4. Encode and to string the hash
// string representation (similar to UNIX format) string encoded = BitConverter.ToString(hash) // without dashes .Replace("-", string.Empty) // make lowercase //.ToLower(); ;
This would then result in a value of A9419D55933FBCF43BA46087F8F20B22
You can also create a random byte array using RNGCryptoServiceProvider but you would then need to persist that byte array to the database and use it in your user authentication challenge routine.