I'm in a bit of a pickle.

I've got an IIS application which accesses an SQL database (on a different machine). This already means that:

a) the IIS application needs to have a connection string to the database containing the password
b) the IIS application needs to run using an AD identity which has access to the SQL database

Option b) seems to be more secure.

However, there's a secondary requirement:
The database mentioned earlier contains sensitive information which is AES encrypted. The IIS application has stores the AES key locally and also encrypts it using DPAPI (to avoid storing it in plain-text). DPAPI has a small issue however:

1) If I let the IIS application run using the ApplicationPoolIdentity role then DPAPI works fine
2) If I let the IIS application run as a specific AD user, then DPAPI fails to decrypt data after an IISRESET

As you can see, b) conflicts with 1), and a) conflicts with 2).

How should I tackle this problem?

  • Are you asking how the application should be coded for properly securing that data or how you should configure an existing app ?
    – Stephane
    Feb 18, 2014 at 10:53
  • I'm not looking for coding solutions - I'm looking for a general description on how such a system should look like and what technologies I should use to make things secure.
    – MBender
    Feb 18, 2014 at 11:10
  • In 2), are you trying to decrypt data in DPAPI that was encrypted with a different user's credentials?
    – RJFalconer
    Feb 18, 2014 at 12:25
  • Absolutely not @RJFalconer! I've found that, for some reason, an IIS application cannot decrypt data encrypted using DPAPI after an IISRESET when using an AD user as the applications identity - even if it was encrypted by said application.
    – MBender
    Feb 18, 2014 at 13:44

1 Answer 1


DPAPI actually works through 2 pretty simple function calls: CryptProtectData and CryptUnprotectData.

To make a long story short, CryptProtectData has two mode of operation: User or system. If you use the user mode (default), then the data is encrypted using the current user logon data. It means that you can only sucessfully call CryptUnprotectData on the same data from the same user context as the one you called CryptProtectData from. (in "system" mode, any process running on that same machine can decrypt the data but not from another system: no too good when the data is in a database).

This means that, if you initially encrypted your data in the SQL server database using a specific AD user account, you're permanently limited to using this user to access it. (This might be considered a defect or a feature depending on the application).

What does it means to you? Well, unless you can change the way the application works or you're willing to reset encrypted data completely, you cannot change the identity used by the web application process.

The good news, however, is that this doesn't have to be insecure: if your web application is an ASP.NET app and uses connection strings stored in the web.config file in a standard way, you can protect them using the DAPI as well but this time with a delegate to the system. Microsoft has a pretty lengthy explanation on how to do that.

Finally, there is always the usual way to dead with that kind of issues: contact the application developers: they are the ones that can tell you exactly what is supported and how. If necessary, they are the ones that can also make the necessary changes to their system to reach the security goals that you have set.

Edit: There is an additional element that you must take into account in your case: when using DAPI, the master key used for encryption is stored in the user profile.

This means that, when you're using a virtual user account (as the ones created for you when running a web app under AppPoolidentity), DAPI actually will not be persisted or reloaded since there is no actual profile created and you will experience the issue you describe: IISreset causes the application to lose its master encryption key because it cannot persist it.

To solve that, you can switch to switch to the NetworkService identity for your web application pool. You will lose the segregation of user provided by the virtual account but, beyond that, it should work in the same way. Microsoft also suggests that you check the "LoadUserProfile" property of the web application pool but I'm dubious that changing it will solve your issue on its own: try it but my guess is that you'll have to use NetworkService as well.

  • 1
    You missed a very importantpart of my question - data stored in SQL is encrypted using AES, and the AES key is encrypted locally using DPAPI to prevent storing it in plain-text by the IIS application. I've edited my question slightly - hopefully this will be more clear now. I am NOT trying to use DPAPI to decrypt data encrypted by another user.
    – MBender
    Feb 18, 2014 at 13:40
  • Right. It does not, however, fundamental change my answer: DAPI still limit the decryption to the same user that encrypted the data and if you change the identity of the web app, you're changing that user.
    – Stephane
    Feb 18, 2014 at 13:55
  • But I've never changed the identity of the web app! As I wrote - if, from the very start, it's working as an AD user, then it won't be able to decrypt what it encrypted earlier after an IISRESET...
    – MBender
    Feb 18, 2014 at 23:16
  • 1
    Also, to note - the IIS application first encrypts the AES key. If it's running using an AD identity it won't be able to later decrypt it (after IISRESET). The only relevant part of your answer is the part about encrypting web.config files...
    – MBender
    Feb 19, 2014 at 11:16
  • You're right: there is something missing in my answer. I'm adding it
    – Stephane
    Feb 19, 2014 at 13:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .