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?
Using a tool like Reflector, you can see what the membership provider does.
This is what has worked for me in the past (assumes passwordFormat 1, i.e. SHA1):
public static string GenerateHash(string pwd, string saltAsBase64)
{
byte[] p1 = Convert.FromBase64String(saltAsBase64);
return GenerateHash(pwd, p1);
}
public static string GenerateHash(string pwd, byte[] saltAsByteArray)
{
System.Security.Cryptography.SHA1 sha = new System.Security.Cryptography.SHA1CryptoServiceProvider();
byte[] p1 = saltAsByteArray;
byte[] p2 = System.Text.Encoding.Unicode.GetBytes(pwd);
byte[] data = new byte[p1.Length + p2.Length];
p1.CopyTo(data, 0);
p2.CopyTo(data, p1.Length);
byte[] result = sha.ComputeHash(data);
string res = Convert.ToBase64String(result);
return res;
}
Where saltAsBase64
is from the PasswordSalt
column of the aspnet_Membership
table.
EDIT:
Example usage:
string pwd = "Letmein44";
string saltAsBase64 = "SuY4cf8wJXJAVEr3xjz4Dg==";
string hash = GenerateHash(pwd, saltAsBase64);
// hash : "mPrDArrWt1+tybrjA0OZuEG1P5w="
Best Answer
Steve, the UserId is not hashed. You may be confusing UserName with UserId (ProviderUserKey) which is a Guid.
In the context of your other questions: You should reference this code in both the code that you use to create a new user in order to log the initial password hash, salt and format AND in the OnPasswordChanging so that you can check/reject/insert.
This will get the relevant information for the currently logged in user: