I need to store and retrieve sensitive data from a local database - this data is used by a web application.
In order to protect said data I've opted to make use of the ProtectedData
class.
The IIS application is running using a specific AD user (Identity property in the Advanced Settings).
Everything works fine until I do an IISRESET - at this point, it seems that the identity is changed for the purposes of the ProtectedData
class, and I'm left with data I cannot decrypt - I'm getting a Key not valid for use in specified state
exception.
Here's the code I'm using:
static public string Encrypt(string data)
{
var encryptedData = ProtectedData.Protect(System.Text.Encoding.UTF8.GetBytes(data), entropy, DataProtectionScope.CurrentUser);
return Convert.ToBase64String(encryptedData);
}
static public string Decrypt(string base64string)
{
var encryptedData = Convert.FromBase64String(base64string);
return System.Text.Encoding.UTF8.GetString(ProtectedData.Unprotect(encryptedData, entropy, DataProtectionScope.CurrentUser));
}
The entropy
is obviously static for my application.
What's going on? I was under the impression that DataProtectionScope.CurrentUser
will use, as the name implies, the current user - which should be, to my knowledge, the application pool identity. Why does it seem like this is changed when I perform an IISRESET?
I had the exact error when using ASP.NET Core Data Protection API, and for those of you who has this error, please confirm that LoadUserProfile was enabled for the Application Pool User.
Whilst I don't know why this was happening, I changed the code to use AES encryption instead - this is working fine.
While not an answer to the problem per-say I think it's a valid workaround that deserves mentioning.
EDIT:
I think I've found what was causing the issue (I still don't exactly know WHY this is happening, but I did notice something today).
If the web application is using the ApplicationPool identity, then all is fine and well and DPAPI should continue working after an IISRESET. However if I change the identity to a specific user defined in AD, then things go haywire after the application pool is recycled.
Lucky for me In this particular case I neither need a specific AD user any more and the main encryption is based on AES (DPAPI can't be used to access a shared resource when load balancing comes into the equation) with DPAPI only being used to encrypt the local copy of the AES keys.