【问题标题】:Maintain ASP.Net membership passwords during machine key change在机器密钥更改期间维护 ASP.Net 成员密码
【发布时间】:2011-05-04 17:11:09
【问题描述】:

是否有实用程序或代码示例可以使用旧密钥解密,然后使用新密钥加密 ASP.Net 会员用户的密码?

【问题讨论】:

    标签: asp.net asp.net-membership


    【解决方案1】:

    提到的解决方法都不适合我。 我的解决方案如下。它首先以明文形式存储密码,然后使用新的 MachineKey 再次对其进行重新加密。

    Machine Key Change

    【讨论】:

      【解决方案2】:

      这是我对解决方案的最佳猜测,但我还没有机会测试它。它依赖于您当前提供者的以下设置:

      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
      }
      

      让我知道这是否适合您。

      【讨论】:

      • 很好,如果可行,它可以避免写入中间位置,而这正是我最终所做的。我会测试一下。
      • section.DecryptionKey = "oldkey";是只读的,不能设置..除非有办法覆盖它我最终检索/解密首先保存到文件然后更改密钥并更新密码。
      • 看起来很有希望,但 typeof(MachineKeySection).GetMethod() 返回 null。
      • 您可能需要在配置中添加 MachineKey 部分。我不太确定。
      【解决方案3】:

      我认为您可以通过即时设置密钥来做到这一点:

      您可能必须扩展 SqlMembershipProvider(或您使用的任何东西)才能访问 protected DecryptPassword 方法。

          MachineKeySection section = (MachineKeySection)WebConfigurationManager.GetSection("system.web/machineKey");
      
      section.DecryptionKey = "old";
      // Read old password
      section.DecryptionKey = "new";
      // Store new password
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-25
        • 1970-01-01
        • 1970-01-01
        • 2011-02-01
        • 2011-02-22
        • 2019-05-08
        • 2011-11-21
        相关资源
        最近更新 更多