我发现很少有关于将现有数据库从加密密码转换为哈希密码的信息。 (我能够找到关于转换另一种方式的更多信息,但它没有多大帮助。)
正如大多数人所知,更改web.config中的passwordFormat
设置只会影响新用户。我有一个包含几百个用户的数据库,我想将它们转换为使用散列密码而不更改现有密码。
是否还有其他人熟悉如何处理这个问题?感谢您的任何提示。
答案 0 :(得分:14)
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);
}
}
答案 1 :(得分:12)
这是我开始的方法,看看我有多远:
所以它是这样的:
<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());
}
答案 2 :(得分:1)
出于安全考虑,在数据库中从加密密码切换到哈希绝对是正确的决定。
通常,要从现有的加密密码中创建哈希值,首先应解密它们然后对它们进行哈希处理。请注意,您将丢失(当您最终切换时)原始密码。相反,您将拥有用户密码的唯一指纹(哈希)。
还要考虑使用salt进行散列(防御rainbow tables等),并查看慢速哈希算法,例如BCrypt(Codeplex&amp; Article: How To Safely Store A Password )出于安全原因而不是像MD5这样的快速原因。
还要记住,将来更换散列算法比将其从ecryption更改为hash更加省力。所以你想第一次就做好;)
答案 3 :(得分:0)
我会提醒你不要随意散列你的密码,因为这种方法有很多警告。这Blog post about hashing passwords对我非常有洞察力,我认为你应该阅读它。为什么要使用散列密码而不是加密?