Back to Blog

[SOLVED] Using an in-memory repository. Keys will not be persisted to storage. – ASP.NET Core under IIS

November 8, 2017

By Matt Mombrea
No Comments

.NET Core Data Protection

One of the main benefits of building a new .NET project using .NET Core is cross platform deployment, however, IIS will still be a common home for ASP.NET Core web applications.

In netcore 2.0 MVC applications, a transparent feature that is configured during app Startup is Data Protection. Data Protection provides a cryptographic foundation for things like ASP.NET Identity among many others.

When the Data Protection system is initialized, it applies default settings based on the operational environment. These settings are generally appropriate for apps running on a single machine.  – Rick Anderson

The app attempts to detect its operational environment and handle key configuration on its own. (cite)

Default Configuration Logic

  • 1) If the app is hosted in Azure Apps, keys are persisted to the %HOME%\ASP.NET\DataProtection-Keys folder. This folder is backed by network storage and is synchronized across all machines hosting the app.
    • Keys aren’t protected at rest.
    • The DataProtection-Keys folder supplies the key ring to all instances of an app in a single deployment slot.
    • Separate deployment slots, such as Staging and Production, don’t share a key ring. When you swap between deployment slots, for example swapping Staging to Production or using A/B testing, any app using Data Protection won’t be able to decrypt stored data using the key ring inside the previous slot. This leads to users being logged out of an app that uses the standard ASP.NET Core cookie authentication, as it uses Data Protection to protect its cookies. If you desire slot-independent key rings, use an external key ring provider, such as Azure Blob Storage, Azure Key Vault, a SQL store, or Redis cache.
  • 2) If the user profile is available, keys are persisted to the %LOCALAPPDATA%\ASP.NET\DataProtection-Keys folder. If the operating system is Windows, the keys are encrypted at rest using DPAPI.
  • 3) If the app is hosted in IIS, keys are persisted to the HKLM registry in a special registry key that is ACLed only to the worker process account. Keys are encrypted at rest using DPAPI.
  • 4) If none of these conditions match, keys aren’t persisted outside of the current process. When the process shuts down, all generated keys are lost.

For IIS, the item we’re interested in here is #3. The default configuration will store the keys in the system registry, that way the keys persist between AppPool restarts and machine restarts. It also lets you share the same key between applications if necessary (via a configuration addition to Startup.cs).

The Problem

Once you deploy your app and run it under an IIS App Pool, you may find that the Data Protection keys are not being persisted. If you have error logging you’ll see entries like this:

  • No XML encryptor configured. Key may be persisted to storage in unencrypted form.
  • Neither user profile nor HKLM registry available. Using an ephemeral key repository. Protected data will be unavailable when application exits.
  • Using an in-memory repository. Keys will not be persisted to storage.

This means that each time your app pool restarts, new keys will be generated and any encrypted codes or values which have been stored or transmitted will no longer be usable. A basic example of this is a Forgotten Password request using ASP.NET Core Identity. If you request a password reset email, an encrypted URL will be sent in the email for you to click on. If the app pool restarts before you get around to clicking that link, the token will not be able to be decrypted and the reset will fail. This scenario becomes much worse if you’re storing long term encrypted data for later decryption.

So what is happening? Why is the default storage method of the system registry failing?

The Solution

This issue stems from a bug in IIS itself which may or may not ever be corrected. In order to work around the issue, it’s necessary for you to edit your App Pool to enable User Profile Loading. Once you set your App Pool to load the user profile for the application pool identity, the application will have permission to read and write to the system registry as intended.

Alternatively, you can configure Data Protection to use a different method of key storage, like a UNC share.

 

 

 

Matt Mombrea

Matt Mombrea

Matt is a longtime entrepreneur and software engineer. He also sits on the board of Computer Science at SUNY Fredonia. Born and raised in Buffalo, Matt is passionate about building and maintaining great businesses in Buffalo. Apart from leading Cypress North, Matt architects our company’s datacenter, engineers dozens of custom applications, and directs the rest of the development team.

See Matt's Most Recent Posts

Share this post

Leave a Reply

Search our blog

Start A Project

Categories

What's next?

Well...you might like one of these

Article

The Case Against The Use Of Shortened...

I  have a confession. I've haven't clicked on an ow.ly link...

Read article

Article

Marketing O’Clock: Google Confirms...

On this week's episode of Marketing O'Clock, Jess Budde...

Read article

Article

5 Fun (& Helpful) New Social Sites...

Just posted a new article over at Search Engine Land. Five...

Read article