How to easily salt a password in a C# windows form application?

13,665

Solution 1

We had a great discussion a while ago about best practices when salting a password, you might find some great ideas there:

Salting Your Password: Best Practices?

I've found that one of the easiest, while still being fairly secure, is to use a GUID as your salt. It's random and sufficiently long. It works best if you include the string formatting of the GUID (the '{' and '-' characters), but you don't have to.

Remember that the salt has to be unique per item salted and that to be most secure, you should use a cryptographically secure random number generator. Remember also that you have to store your salt along with the password, or you won't be able to check the plaintext version against the hashed version! You can store the salt un-encrypted if you like; I typically put it in a field on the same table as the password. The purpose of the salt isn't to remain hidden, it's to make rainbow tables difficult (hopefully impossible) to compute in a timely manner.

Here's a quick snippet that will work in C#:

RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buffer = new byte[1024];

rng.GetBytes(buffer);
string salt = BitConverter.ToString(buffer);
var saltedPassword = password + salt;

or...

var salt = Guid.NewGuid().ToString();
var saltedPassword = password + salt;

Solution 2

I suppose you are asking for a username along with the password?

In some systems username is used as a salt. (And I think it is OK to do that.) Otherwise you'll need to have your salt stored somewhere and retrieve it before hashing (in case of random-created salt) or have an algorithm which will return the same salt for the same user (and it is not better that just using a plain username).

Personally use the following code:

byte[] GetSaltedPasswordHash(string username, string password)
{
    byte[] pwdBytes = Encoding.UTF8.GetBytes(password);
    // byte[] salt = BitConverter.GetBytes(userId);
    byte[] salt = Encoding.UTF8.GetBytes(username);
    byte[] saltedPassword = new byte[pwdBytes.Length + salt.Length];

    Buffer.BlockCopy(pwdBytes, 0, saltedPassword, 0, pwdBytes.Length);
    Buffer.BlockCopy(salt, 0, saltedPassword, pwdBytes.Length, salt.Length);

    SHA1 sha = SHA1.Create();

    return sha.ComputeHash(saltedPassword);
}

Solution 3

Here's a nice article and another one (which is more adapted to ASP.NET applications).

Share:
13,665

Related videos on Youtube

Sergio Tapia
Author by

Sergio Tapia

I'm a 21 year old professional programmer that likes to read about a wide range of things related to programming. Currently, I'm pounding away at ASP.Net MVC2.

Updated on June 04, 2022

Comments

  • Sergio Tapia
    Sergio Tapia almost 2 years

    How can I easily salt a password from a Textbox.Text?

    Are there some built in wizardry in the .NET framework?

  • Randolpho
    Randolpho almost 14 years
    The second article is better, since it allows for an arbitrary salt size. The first one recommends a 4-byte salt; definitely way to small. Salts should be long. I'm not criticizing you, just placing this here for posterity. :)
  • Adam Houldsworth
    Adam Houldsworth almost 14 years
    If you generate random salts, remember to keep hold of them as you need them to decrypt on the way out.
  • Randolpho
    Randolpho almost 14 years
    @Adam: good point. I originally had a sentence to that effect but have apparently edited it out. I'll put it back in.

Related