I use the following code to store user passwords.
string password = "...";
string user_salt = System.Web.Security.Membership.GeneratePassword(20, 5);
string common_salt = "...";
byte[] hash_target = Encoding.UTF8.GetBytes(password + user_salt + common_salt);
string password_hash = BitConverter.
ToString(new SHA512CryptoServiceProvider().ComputeHash(hash_target)).
Replace("-", string.Empty).
ToUpper();
The user salt is stored together with the hashed password in the database. Additionally, every time a user's password is changed, the user salt is regenerated.
The reasoning behind a common salt and a user salt is: access to the database alone isn't enough to figure out how the hashing works. And then in case someone manages to disassemble the code, the malicious user cannot make use of a single rainbow table.
Is this a good method?
SHA512CryptoServiceProvider
implementsIDisposable
, so it should be assigned to a variable and wrapped in ausing
block. \$\endgroup\$""
is a value andstring.Empty
is a constant declared for this value. This is of course a very well known value but still can be considered magic. \$\endgroup\$