I was just going through one of DavidHayden's articles on Hashing User Passwords.
Really I can't get what he is trying to achieve.
Here is his code:
private static string CreateSalt(int size)
{
//Generate a cryptographic random number.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[size];
rng.GetBytes(buff);
// Return a Base64 string representation of the random number.
return Convert.ToBase64String(buff);
}
private static string CreatePasswordHash(string pwd, string salt)
{
string saltAndPwd = String.Concat(pwd, salt);
string hashedPwd =
FormsAuthentication.HashPasswordForStoringInConfigFile(
saltAndPwd, "sha1");
return hashedPwd;
}
Is there any other C# method for hashing passwords and adding salt to it?
Actually this is kind of strange, with the string conversions - which the membership provider does to put them into config files. Hashes and salts are binary blobs, you don't need to convert them to strings unless you want to put them into text files.
In my book, Beginning ASP.NET Security, (oh finally, an excuse to pimp the book) I do the following
The salt generation is as the example in the question. You can convert text to byte arrays using
Encoding.UTF8.GetBytes(string)
. If you must convert a hash to its string representation you can useConvert.ToBase64String
andConvert.FromBase64String
to convert it back.You should note that you cannot use the equality operator on byte arrays, it checks references and so you should simply loop through both arrays checking each byte thus
Always use a new salt per password. Salts do not have to be kept secret and can be stored alongside the hash itself.
Salt is used to add an extra level of complexity to the hash, to make it harder to brute-force crack.
From an article on Sitepoint:
There is no method automatically doing this in .NET, so you'll have go with the solution above.
What blowdart said, but with a little less code. Use Linq or
CopyTo
to concatenate arrays.Linq has an easy way to compare your byte arrays too.
Before implementing any of this however, check out this post. For password hashing you may want a slow hash algorithm, not a fast one.
To that end there is the
Rfc2898DeriveBytes
class which is slow (and can be made slower), and may answer the second part of the original question in that it can take a password and salt and return a hash. See this question for more information. Note, Stack Exchange is usingRfc2898DeriveBytes
for password hashing (source code here).In answer to this part of the original question "Is there any other C# method for hashing passwords" You can achieve this using ASP.NET Identity v3.0 https://www.nuget.org/packages/Microsoft.AspNet.Identity.EntityFramework/3.0.0-rc1-final