Thursday, April 10, 2014

Changing MachineKey on IIS while using SQLMembership provider

There is business need to change MachineKey after servers was already rolled out and SQLMembership provider created accounts on backend encrypted with MachineKey.
Below code and instructions how to properly do that.
1. Your password setting in SQLMembership provider is configured as "encrypted"
That's really the only requirement for the rest of the things to work.

Process is as follows

1. Create membership provider with setting which allows password decryption (enablePasswordRetrieval as "true") and put passwordFormat setting as "clear".
2. Go through the list of users with this membership provider and find all users which are locked and with passwords which can not be decrypted (happens if passwords were encrypted with wrong MachineKey etc). If locked user is encountered then user is unlocked and his password is reset. If any passwords found which are not decryptable then their passwords are reset to preset password. For the rest of the users add their passwords to in-memory Dictionary<> instance which will provide temporary storage of passwords during decryption process.
3. Run SQL statement on database which marks all passwords for all users as [PasswordFormat] =0 which tells provider that this user stores it's password in clear text format. (It's possible to have mix of users in database with both clear and "encrypted" format.
4. Run code against all users and reset their passwords to their original passwords.

By the end of step 4 you would have all passwords in clear text in database.

5. Change "MachineKey" value in web.config file for this application to value you'd like to use
6. Enumerate all users and get their passwords and store them in memory
7. Run SQL statement to mark their [PasswordFormat]=2 which means "encrypted"
8. Change password to the one stored in memory which will encrypt it on the fly to encrypted format in database using MachineKey
9. Change MachineKey in production database

Entire application can stay online (no downtime is required) during operation. The only part which will be offline is user creation and password changes. You need to make sure pages responsible for user creation and password changes are disabled during operations.