How to change the SQL Membership security question Answer, stored as a hashed value with a PasswordSalt
Posted on 2008-10-21
I am developing a website that uses forms authentication. I have set up the default SQL Membership Provider database for this.
For the Membership SQL Provider, I have set the following: requiresQuestionAndAnswer="true", passwordFormat="Hashed"...etc.
On an page in my site, I am allowing the user to change their security question and answer. In the C# code-behind, I tried using the default stored procedure: aspnet_Membership_ChangePasswordQuestionAndAnswer(appname, username, newQuestion, newAnswer)
to reset the security question and answer. This works; except that the security answer is saved in the Membership table as a STRING value; NOT as a salted, hashed value.
So, then I tried researching how to manually convert the security answer from a string value to a salted/hashed value.
First I tried this: FormsAuthentication.HashPasswordForStoringInConfigFile(saltValue + answerValue, hashtype)....(where hashtype is equal toMembership.HashAlgorithmType). This gave me a hashed value, but not the hashed value I was after; it didn't work for me.
Then I tried implementing this logic...again, this gave me a hashed value, but not the hashed value I needed:
public static string HashStringWithSalt(string answerValue, string saltValue)
byte salt = System.Convert.FromBase64String(saltValue);
byte answer = System.Text.Encoding.Unicode.GetBytes(answerValue);
// Mix together
byte saltWithAnser = new byte[salt.Length + answer.Length];
System.Buffer.BlockCopy(salt, 0, saltWithAnser, 0, salt.Length);
System.Buffer.BlockCopy(answer, 0, saltWithAnser, salt.Length, answer.Length);
// Get hash value and return a base64-encoded string
byte hash = new System.Security.Cryptography.SHA1CryptoServiceProvider().ComputeHash(saltWithAnser);
NOTE: I know that I did not receive the proper hashed values from my trials above because I have added several user accounts to my membership database; lets say UserA and UserB. I have used the same password and same security question/answer for these accounts (obviously for testing purposes only). Then I copied the PasswordSalt value for UserA into UserB's PasswordSalt in the Membership table. Then on my web page, I changed my security answer for UserB, and the security answer hashed value I received did not match the hashed value for UserA's security answer.
I am very new to ASP.NET, and have never set up a website using Forms Authentication before. So I will be greatful for any help...I have been searchign the web for hours and can't seem to find a solution that fits my problem...basically I need to allow the user to reset their security question & answer; and save the security answer as a salted/hashed value.