3

I've developing an asp.net core application to tun on a web far, and I'm using "AddDataProtection" to protect for key encryption at rest like, the documentation recommends, but when I deploy my application and run directly from IIS with AppPool identity, the key is never created and I get errors on the DpapiNG windows logs.

My code is the following:

services.AddDataProtection(opt => opt.ApplicationDiscriminator = ApplicationConfig.dataProtectionApplicationDiscriminator)
            .PersistKeysToFileSystem(new DirectoryInfo(encKeyPath))
            .ProtectKeysWithDpapiNG(string.Format("CERTIFICATE=HashId:{0}", ApplicationConfig.dataProtectionCertThumbprint),
                flags: DpapiNGProtectionDescriptorFlags.None);

Debugging from visual studio, everything runs fine, but I'm running VS under administrator rights, so permission is not an issue here.

I've tried adding permissions to the AppPool App user to the private key it self directly from MMC, but it did not worked, and even gave permission on the full path to the location were the keys should be created like stated here https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview (check first comment) but also it did not worked.

I was only able to make it work by setting the AppPool to run with the identity of an Administrator, but clearly this is a no go, I just wanted to make sure this was a permission issue somewhere.

Is anybody facing the same issue that is able to help?

Regards, André

  • 1
    If you just do services.AddDataProtection().PersistKeysToFileSystem(sharedDataProtectionDirInfo); I guess it worked? It's only the call to DPAPI that has insufficient credentials? Looking at https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-encryption-at-rest, have you tried with protectToLocalMachine: true ? – Daboul Jun 23 '17 at 08:06
  • Yes, by removing DPAPI the key is created, but then again, like the documentation says, this is a no go: "Warning: If you change the key persistence location, the system will no longer automatically encrypt keys at rest since it doesn't know whether DPAPI is an appropriate encryption mechanism." About protectToLocalMachine, ProtectKeysWithDpapiNG does not have an overload for this, only ProtectKeysWithDpapi has. – AndrePinto-NET Jun 23 '17 at 08:47
  • I know it's a no go, it's just to isolate precisely your issue, I might have to work with that in the coming days, I'll see if I run into the same issue. – Daboul Jun 23 '17 at 08:59
  • And if you use simply .ProtectKeysWithDpapiNG() (no params, so that it uses your AD account), is it working? – Daboul Jun 23 '17 at 09:08
  • Although the key is created, It still get errors: Unprotect Key operation failed. Cryptographic Parameters: Protector Name: SID Recipient Type: SYMMETRIC KEY ENCRYPTION Flags: 0x40 Failure Information: Return Code: 0x80070005 Unprotect Secret operation failed. Cryptographic Parameters: Flags: 0x40 Failure Information: Return Code: 0x8009002C – AndrePinto-NET Jun 23 '17 at 10:01
  • 0x8009002C means The specified data could not be decrypted.(https://msdn.microsoft.com/en-us/library/windows/desktop/dd542646(v=vs.85).aspx) There are some suggestions here to investigate https://github.com/aspnet/DataProtection/issues/205 Could it help? – Daboul Jun 23 '17 at 10:11
  • No, because I cannot use ProtectKeysWithDpapiNG() without parameters, because like this it won't work on a server farm, which is my case. – AndrePinto-NET Jun 23 '17 at 10:26
  • Are you sure about that? No params means it will use the user AD account to encrypt, and if this user is a domain user shared between your servers, then it might end up working fine, don't you think? – Daboul Jun 23 '17 at 10:54
  • If it is running with IIS AppPool identity it is not a solution, because the user belongs the the computer, not to the domain, and in any csae I want to use a certificate, not a user account – AndrePinto-NET Jun 23 '17 at 11:53
  • We are using a technical user to run our application pools, so it would be working for us but in your case, you might need to get this certificate working. Let see if someone can come up with an idea, I might give it a try at some point also. – Daboul Jun 23 '17 at 13:20
  • Did you solve this problem? I'm having the same issue with ProtectKeysWithDpapi. The key does not get created when I deploy to IIS. – Edminsson Jan 17 '18 at 11:19
  • No, everything I tried failed. Ended up creating a domain user, and set the AppPoll on IIS to run under that user on all servers on the farm, this way I was able to avoid the error. – AndrePinto-NET Jan 18 '18 at 12:11

1 Answers1

1

Most likely your issue is you are trying to store your keys somewhere in a folder path that you are cobbling together (or even by using the default path that AddDataProtection provides) that uses an environment path such as %LOCALAPPDATA%. Example: "%LOCALAPPDATA%\ASP.NET\DataProtection-Keys". Usually, by default IIS DOES NOT set up your app pool accounts with environment path variables such as %LOCALAPPDATA%. The value ends up being blank and your app then tries to write keys to the wrong folder (such as \ASP.NET\DataProtection-Keys instead of %LOCALAPPDATA%\ASP.NET\DataProtection-Keys).

Fix: Within %WINDIR%\System32\inetsrv\config\applicationHost.config set setProfileEnvironment=true. I think you have to restart IIS as well.

Nez
  • 59
  • 4