【发布时间】:2011-05-04 17:11:09
【问题描述】:
是否有实用程序或代码示例可以使用旧密钥解密,然后使用新密钥加密 ASP.Net 会员用户的密码?
【问题讨论】:
标签: asp.net asp.net-membership
是否有实用程序或代码示例可以使用旧密钥解密,然后使用新密钥加密 ASP.Net 会员用户的密码?
【问题讨论】:
标签: asp.net asp.net-membership
提到的解决方法都不适合我。 我的解决方案如下。它首先以明文形式存储密码,然后使用新的 MachineKey 再次对其进行重新加密。
【讨论】:
这是我对解决方案的最佳猜测,但我还没有机会测试它。它依赖于您当前提供者的以下设置:
enablePasswordRetrieval="true" requiresQuestionAndAnswer="false" passwordFormat="Encrypted"
它还假设新的机器密钥已经在配置文件中。
创建以下类(感谢 mootinator 对此的快速启动)
using System.Reflection;
using System.Web.Configuration;
using System.Web.Security;
namespace MyNamespace
{
public class MySqlMembershipProvider : SqlMembershipProvider
{
protected override byte[] DecryptPassword(byte[] encodedPassword)
{
MachineKeySection section = (MachineKeySection)WebConfigurationManager.GetSection("system.web/machineKey");
section.DecryptionKey = "oldkey"; // TODO: Set your old key here
MethodInfo method = typeof(MachineKeySection).GetMethod("EncryptOrDecryptData", BindingFlags.Instance | BindingFlags.NonPublic);
return (byte[])method.Invoke(section, new object[] { encodedPassword, null, 0, encodedPassword.Length, 0, false, false });
}
}
}
在您的 web.config 中:
<membership defaultProvider="DefaultSqlMembershipProvider">
<providers>
<clear/>
<add name="DefaultSqlMembershipProvider" connectionStringName="MembershipConnectionString" enablePasswordRetrieval="true" requiresQuestionAndAnswer="false" applicationName="TODO" passwordFormat="Encrypted" type="System.Web.Security.SqlMembershipProvider"/>
<add name="MySqlMembershipProvider" connectionStringName="MembershipConnectionString" enablePasswordRetrieval="true" requiresQuestionAndAnswer="false" applicationName="TODO" passwordFormat="Encrypted" type="MyNamespace.MySqlMembershipProvider"/>
</providers>
</membership>
使用以下代码更改密码:
MembershipProvider retrievePasswordProvider = Membership.Providers["MySqlMembershipProvider"];
foreach (MembershipUser user in Membership.GetAllUsers())
{
MembershipUser retrievePassworedUser = retrievePasswordProvider.GetUser(user.UserName, false);
string password = retrievePassworedUser.GetPassword(); // get password using old key
user.ChangePassword(password, password); // change password to same password using new key
}
让我知道这是否适合您。
【讨论】:
typeof(MachineKeySection).GetMethod() 返回 null。
我认为您可以通过即时设置密钥来做到这一点:
您可能必须扩展 SqlMembershipProvider(或您使用的任何东西)才能访问 protected DecryptPassword 方法。
MachineKeySection section = (MachineKeySection)WebConfigurationManager.GetSection("system.web/machineKey");
section.DecryptionKey = "old";
// Read old password
section.DecryptionKey = "new";
// Store new password
【讨论】: