How can I validate hashed ASP.NET service passwords programmatically?
I have a website in which I am migrating membership from ASP.NET services to a custom provider. I would like to migrate existing users without them needing to change their passwords.
The users' passwords are currently stored using a one-way encryption. The only option for me is to use the same salt and passwords as the ASP services and validate against them with my custom provider.
Here is the configuration used to currently hash the passwords with ASP.NET services.
<membership defaultProvider="AspNetSqlMembershipProvider" userIsOnlineTimeWindow="15" hashAlgorithmType="">
<providers>
<clear/>
<add connectionStringName="dashCommerce" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="dashCommerce" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10" passwordStrengthRegularExpression="" minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0" name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</providers>
</membership>
I have been pulling my hair out trying to write the code needed to validate passwords against hashes generated by this config.
This is what I have so far. Any help would be greatly appreciated.
private static string Cr开发者_开发百科eatePasswordHash(string Password, string Salt)
{
return FormsAuthentication.HashPasswordForStoringInConfigFile(Password + Salt, "SHA1");
}
//string hashOldPassword = utl.generateHash(txtpassword.Text);
string hashOldPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(txtpassword.Text,"SHA1");
//string hashOldPassword = Membership.Provider.GetPassword(Page.User.Identity.Name.ToString(), string.Empty);
MembershipUser user = Membership.GetUser();
//string hashOldPassword = user.GetHashCode(
if (txtnewpassword.Text.Length < 7)
{
}
var userId = user.ProviderUserKey;
var user1 = Membership.GetUser();
MembershipPasswordFormat passwordFormat;
string passwordSalt;
string password;
SqlConnection sqlconn = new SqlConnection(Connect.Connection());
//var cstring = ConnectionStrings[Connect.Connection()];
using (var conn = new SqlConnection(sqlconn.ConnectionString))
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "select PasswordFormat,PasswordSalt,Password from aspnet_Membership where UserId=@UserId";
cmd.Parameters.AddWithValue("@UserId", userId);
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
if (rdr != null && rdr.Read())
{
passwordFormat = (MembershipPasswordFormat)rdr.GetInt32(0);
// passwordFormat = rdr.GetString(0);
passwordSalt = rdr.GetString(1);
password = rdr.GetString(2);
if (hashOldPassword == password)
{
user.ChangePassword(txtpassword.Text, txtnewpassword.Text);
}
else
{
}
//if(password.ToString()!=txtpassword)
}
else
{
throw new Exception("An unhandled exception of type 'DoesntWorkException' has occured");
}
}
I dug through reflector and found the code used to compute hashes.
private static string CreatePasswordHash(string Password, string Salt)
{
string passwordFormat = SettingManager.GetSettingValue("Security.PasswordFormat");
if (String.IsNullOrEmpty(passwordFormat))
passwordFormat = "SHA1";
byte[] bytes = Encoding.Unicode.GetBytes(Password);
byte[] src = Convert.FromBase64String(Salt);
byte[] dst = new byte[src.Length + bytes.Length];
byte[] inArray = null;
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
HashAlgorithm algorithm = HashAlgorithm.Create(passwordFormat);
inArray = algorithm.ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
This worked.
精彩评论