Maintain ASP.Net membership passwords during machine key changes

Is there a utility or sample code that can decrypt using the old key and then encrypt passwords with the new key for ASP.Net membership users?

+3
source share
3 answers

None of the workarounds worked for me. My solution is below. It includes first storing passwords in clear text, and then re-encrypting them using the new MachineKey.

Change car key

+2
source

This is my best guess for a solution, but I did not have the opportunity to test it. It uses the following settings for your current provider:

enablePasswordRetrieval="true" requiresQuestionAndAnswer="false" passwordFormat="Encrypted"

, .

( mootinator jumpstart )

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
}

, .

+1

I think you could do this by setting the key on the fly:

You may need to expand SqlMembershipProvider(or whatever you use) to access the method protected DecryptPassword.

    MachineKeySection section = (MachineKeySection)WebConfigurationManager.GetSection("system.web/machineKey");

section.DecryptionKey = "old";
// Read old password
section.DecryptionKey = "new";
// Store new password
0
source

Source: https://habr.com/ru/post/1772923/


All Articles