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?
SHA512CryptoServiceProviderimplementsIDisposable, so it should be assigned to a variable and wrapped in ausingblock. \$\endgroup\$""is a value andstring.Emptyis a constant declared for this value. This is of course a very well known value but still can be considered magic. \$\endgroup\$