ASP.NET membership salt?

chobo2 picture chobo2 · Aug 12, 2009 · Viewed 24.1k times · Source

How does ASP.NET membership generate their salt key and then how do they encode it (that is, is it salt + password or password + salt)?

I am using SHA-1 with my membership, but I would like to recreate the same salts so the built-in membership stuff could hash the stuff the same way as my stuff can.

Edit 2: Never mind. I misread it and was thinking it said bytes, not bits. So I was passing in 128 bytes, not 128 bits.

Edit: I been trying to make it so. This is what I have,

public string EncodePassword(string password, string salt)
{
    byte[] bytes = Encoding.Unicode.GetBytes(password);
    byte[] src = Encoding.Unicode.GetBytes(salt);
    byte[] dst = new byte[src.Length + bytes.Length];

    Buffer.BlockCopy(src, 0, dst, 0, src.Length);
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);

    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");

    byte[] inArray = algorithm.ComputeHash(dst);

    return Convert.ToBase64String(inArray);
}

private byte[] createSalt(byte[] saltSize)
{
    byte[] saltBytes = saltSize;

    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    rng.GetNonZeroBytes(saltBytes);

    return saltBytes;
}

So I have not tried to see if the ASP.NET membership will recognize this yet the hashed password looks close. I just don't know how to convert it to base64 for the salt.

I did this

byte[] storeSalt = createSalt(new byte[128]);
string salt = Encoding.Unicode.GetString(storeSalt);
string base64Salt = Convert.ToBase64String(storeSalt);

int test = base64Salt.Length;

Test length is 172 which is well over the 128 bits so what am I doing wrong?

This is what their salt looks like

vkNj4EvbEPbk1HHW+K8y/A==

This is what my salt looks like

E9oEtqo0livLke9+csUkf2AOLzFsOvhkB/NocSQm33aySyNOphplx9yH2bgsHoEeR/aw/pMe4SkeDvNVfnemoB4PDNRUB9drFhzXOW5jypF9NQmBZaJDvJ+uK3mPXsWkEcxANn9mdRzYCEYCaVhgAZ5oQRnnT721mbFKpfc4kpI=

Answer

Kelly Gendron picture Kelly Gendron · Aug 12, 2009

What is default hash algorithm that ASP.NET membership uses? has a good discussion of their default algorithm.

I hope that helps!

Edit- The answer I was referring to is the code in the top post,

   public string EncodePassword(string pass, string salt)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(pass);
        //byte[] src = Encoding.Unicode.GetBytes(salt); Corrected 5/15/2013
        byte[] src = Convert.FromBase64String(salt); 
        byte[] dst = new byte[src.Length + bytes.Length];
        Buffer.BlockCopy(src, 0, dst, 0, src.Length);
        Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
        HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
        byte[] inArray = algorithm.ComputeHash(dst);
        return Convert.ToBase64String(inArray);
    } 

They are combining Unicode Salt + Pass using BlockCopy

-- In response to your question:

Both algorithms are necessary and fulfill different roles...

RNG Crypto is used to generate the salt. It is basically a long string of random data. This is generated and stored on a per user basis. Typically this is done when a user is created or a password is changed.

BlockCopy is just the method they use to combine the salt with the password. The above code essentially equates to salt + password.

You aren't going to be able to recreate a salt value as it is completely random. It is, however, stored for each user by the framework.

Combining the salt with the password and hashing it using the technique above will allow you to verify users passwords using the hashed value stored by the framework.

I think we both read your question differently. The code I posted won't generate your salt, but it will let you use it in a way that is compatible with ASP.NET membership.

Sorry my explanation isn't the best- does that answer your question?