I'm running a C# application that needs to encrypt/decrypt files (using NTFS's EFS encryption) on behalf of a specific user account--a user account other than the one under which the application is running. I didn't want to go through the hassle of firing up a new process (using CreateProcessAsUser) because I'd have to worry about IPC and it'd be less performant. The question I had was: is it possible to encrypt/decrypt files as a user other than the one under which the process is running within that process? I couldn't find any resource on the web that stated an answer definitively, so I wrote some code to try it. The answer is: yes.
Here are the steps (it involves a mix of Interop and managed methods):
-
Get a handle to the desired user (the one whose encryption key you want to use) by calling LogonUser. (You'll need the user's password.)
-
Load the user's profile (aka registry hive) by calling LoadUserProfile.
-
Construct a WindowsIdentity object using the handle provided by the call in step 1.
-
Invoke WindowsIdentity.Impersonate().
-
Perform any file I/O -- it'll be in the context of that user. The user's encryption key will be used with any File.Encrypt() / FileInfo.Encrypt() invocation.
-
Unload the profile by calling UnloadUserProfile.
-
Close the user handle by calling CloseHandle.
You can do steps 1-4 in the constructor of an IDisposable object and do steps 5-7 in the Dispose() method to ensure proper resource cleanup.