我发现关于将现有数据库从加密密码转换为哈希密码的信息非常少。(我能够找到更多有关另一种方式的转换的信息,但它并没有什么帮助。)
正如大多数人所知道的那样,在web.config中更改passwordFormat
设置只影响新用户。我有一个包含几百个用户的数据库,我想将他们转换为使用哈希密码,而不改变这些现有密码。
是否有其他人了解如何处理这个问题?感谢任何提示。
我发现关于将现有数据库从加密密码转换为哈希密码的信息非常少。(我能够找到更多有关另一种方式的转换的信息,但它并没有什么帮助。)
正如大多数人所知道的那样,在web.config中更改passwordFormat
设置只影响新用户。我有一个包含几百个用户的数据库,我想将他们转换为使用哈希密码,而不改变这些现有密码。
是否有其他人了解如何处理这个问题?感谢任何提示。
Greg的解决方案是个好的开端,但它不会影响现有用户。SqlMembershipProvider通过在密码表中存储PasswordFormat(0 = clear,1 = Hashed,2 = Encrypted)来保护现有用户和密码。更改提供程序密码格式仅影响对用户表的插入。为了将现有用户的密码转换为Hashed,您必须更改每个条目的PasswordFormat参数。以下是一个简单的方法:
void HashAllPasswords()
{
var clearProvider = Membership.Providers["SqlProvider_Clear"];
var hashedProvider = Membership.Providers["SqlProvider_Hashed"];
int dontCare;
if (clearProvider == null || hashedProvider == null) return;
var passwords = clearProvider.GetAllUsers(0, int.MaxValue, out dontCare)
.Cast<MembershipUser>().ToDictionary(u => u.UserName, u => u.GetPassword());
using (var conn = new SqlConnection(
ConfigurationManager.ConnectionStrings[0].ConnectionString))
{
conn.Open();
using (var cmd = new SqlCommand(
"UPDATE [aspnet_Membership] SET [PasswordFormat]=1", conn))
cmd.ExecuteNonQuery();
}
foreach (var entry in passwords)
{
var resetPassword = hashedProvider.ResetPassword(entry.Key, null);
hashedProvider.ChangePassword(entry.Key, resetPassword, entry.Value);
}
}
<membership defaultProvider="HashedProvider">
<providers>
<clear />
<add name="HashedProvider" connectionStringName="MembershipConnectionString" enablePasswordRetrieval="false" requiresQuestionAndAnswer="false" applicationName="MyApp" passwordFormat="Hashed" type="System.Web.Security.SqlMembershipProvider" />
<add name="EncryptedProvider" connectionStringName="MembershipConnectionString" enablePasswordRetrieval="true" requiresQuestionAndAnswer="false" applicationName="MyApp" passwordFormat="Encrypted" type="System.Web.Security.SqlMembershipProvider" />
</providers>
</membership>
代码:
SqlMembershipProvider hashedProvider = (SqlMembershipProvider)Membership.Providers["HashedProvider"];
SqlMembershipProvider encryptedProvider = (SqlMembershipProvider)Membership.Providers["EncryptedProvider"];
int unimportant;
foreach (MembershipUser user in encryptedProvider.GetAllUsers(0, Int32.MaxValue, out unimportant ))
{
hashedProvider.ChangePassword(user.UserName, user.GetPassword(), user.GetPassword());
}
我建议你不要随意哈希密码,因为这种方法有很多注意事项。对我来说,关于哈希密码的博客文章非常有见地,我认为你应该阅读一下。为什么你想要哈希密码而不是加密?