Unhandled exception. System.Security.Cryptography.CryptographicException: The key {....} was not found in the key ring
Asked Answered
C

6

10

I am using VS 2022 with dotnet core web api and below is my code in Program.cs for data protection.

string appName = "My_WebAPI";
var dataProtectionProvider = DataProtectionProvider.Create(appName);
IDataProtector dataProtector = dataProtectionProvider.CreateProtector(ApplicationConstants.ENCRYPTION_KEY);
string DbContext = dataProtector.Unprotect(builder.Configuration.GetConnectionString("DbContext"));

This code works perfectly fine in IIS express, but when I hosted in IIS I get the below error.

Unhandled exception. System.Security.Cryptography.CryptographicException: The key {....} was not found in the key ring. For more information go to http://aka.ms/dataprotectionwarning at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData) at Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.Unprotect(IDataProtector protector, String protectedData)

Please help me to resolve this, I could not find any similar questions in DotNet Core 6. There were changes in "ConfigureServices" from DotNet Core 5 to 6. I managed to make it work for 6 but it worked only in DEBUG mode. After hosting to IIS, did not work.

Also, one more thing observed when I moved the project to a new folder, previously encrypted data were unable to decrypt. Not sure why is it so. I forgot to capture the exception.

EDIT Adding to the above, The data which was encrypted while running in IIS Express were not able to decrypt while running in IIS. Anyone faced the same issue ? I freshly tried to encrypt and decrypt after hosting in IIS it works and no exception found like The key {....} was not found in the key ring But I might have to connect my code base and debug the data which was encrypted from the application hosted in IIS.

Thanks.

Curhan answered 10/1, 2022 at 2:56 Comment(1)
V
5

I experience the similar issue while transferring data across programmes. It functions locally, but.net core prevents retrieving the encrypted value when hosted on a server. It functions when I add the data protection file storage.

You can use file storage, database stores, redis, and azure storage depending on your needs.(https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-storage-providers?view=aspnetcore-7.0&tabs=visual-studio).

builder.Services.AddDataProtection()
  .SetApplicationName("App Name")
  .PersistKeysToFileSystem(new DirectoryInfo(@"C:\temp-keys\"))
  .ProtectKeysWithDpapi();
Viceregal answered 5/1, 2023 at 18:53 Comment(0)
M
2

Following steps should fix that:

  1. In IIS Manager, Application Pool, Advanced Settings..., change Identity to Built-in account: NetworkService.
  2. In IIS Manager, Application Pool, Advanced Settings..., change Load User Profile to True
  3. Restart the IIS Server.
Multifoliate answered 26/6, 2022 at 14:41 Comment(2)
It doesn't work in my caseCoaptation
Sadly it didn't work for me eitherGrip
H
1

I ran into this error when I changed the runtime of a project from .NET 6 to .NET 7 and deployed it to IIS.

The issue for me was client side. Clearing site data fixed the error. I suppose having the old cookies and/or local storage data from the .NET 6 app wasn't compatible with .NET 7.

Horseleech answered 22/8, 2023 at 22:14 Comment(0)
O
0

I got this when using a load-balancer in production. There were multiple machines that all had their own set of keys. Solved it by storing the keys in the database. First implement two methods from IXmlRepository that will store and get the keys:

public class SqlKeyPersistor : IXmlRepository
{
    public IReadOnlyCollection<XElement> GetAllElements(){
        ...
    }

    public void StoreElement(XElement element, string friendlyName)
    {
        ...
    }
}

Then in the startup:

SqlKeyPersistor persist = new SqlKeyPersistor(sqlConnectionstring, serviceName, tableName);

builder.Services.AddDataProtection()
  .SetApplicationName("App Name")
  .Services.Configure<KeyManagementOptions>(options =>
  {
      options.XmlRepository = persist;
  });

You should also have a task that cleans up expired keys.

There are some pre-built storage options like Azure, Redis, EntityFramework, etc... https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-storage-providers?view=aspnetcore-7.0&tabs=visual-studio

Ornamented answered 31/10, 2023 at 8:33 Comment(0)
S
0

I was inspired by @Viki answers, And I got this to work on MAC:

Services.AddDataProtection()
    .SetApplicationName("App")
    .PersistKeysToFileSystem(new DirectoryInfo(@"/var/share/directory"))
    .UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration() {
        EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
        ValidationAlgorithm = ValidationAlgorithm.HMACSHA256
    });
docker run -v /var/share/directory:/var/share/directory -p 8080:80 my-app

We have to use var in MAC, more information can be found here: Mounts denied. The paths ... are not shared from OS X and are not known to Docker

Sattler answered 28/3 at 20:0 Comment(0)
C
0

I had just deployed a .NET Core Blazor application to my server and restarted IIS, then refreshed the browser tab when I received this message. Even restoring the previous version of the app and refreshing the browser tab didn't work. In my case, I simply closed the tab and reopened it and it worked.

Candra answered 10/6 at 19:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.