Secure encryption / decryption of appsettings.json on the server

How to protect the encryption key used to encrypt sensitive data in my appsettings.json web application?

I would like to protect sensitive data in my web application configuration.

In ASP.NET MVC4 applications, we did this as follows:

  • Sensitive data (for example, the password in the connection string) is not added directly to web.config (or web.prod.config , etc.), instead, a placeholder variable is written.
  • During deployment, our deployment service (Octopus) will retrieve sensitive data from it and overwrite the variable in web.config .
  • The deployment process will then encrypt sensitive sections of web.config using aspnet_regiis.exe .

Now we are using ASP.NET Core, the process we are running is a little different.

  • appsettings.json contains placeholder variables for sensitive data, similar to how web.config previously worked.
  • The deployment process replaces the placeholder with sensitive data from it with a secure store, as before.
  • Instead of using aspnet_regiis , I think I need:

    a) create your own tool to encrypt parts of the appsettings.json file.

    b) create your own configuration provider that can decrypt (all / parts) appsettings.json

I do not understand how to protect the encryption key used for (a) and (b). The old method used the server server key to encrypt the file.

The threat I'm trying to mitigate is getting access to appsettings.json on the server and reading sensitive data (for example, database password, etc.).

I am also interested in alternative ways to mitigate this threat and / or other problems with this approach as a whole.

+7
asp.net-core encryption connection-string
source share
4 answers

If you do not trust the server, you cannot protect the "secrets" that you store on this server.

Explanation:

No matter what kind of “secure” (= unsecured) scheme you invent — when the application starts, it should be possible to “decrypt” the secrets into some kind of “useful” form.

This means that all the "keys" (certificates, etc.) necessary for "decryption" must exist on this server and be accessible to the application (otherwise the application cannot start).

This means that some bad guy who gets access to the server and the application can also access all the “keys” on it and decrypt your secrets. Maybe copying files, maybe decompiling your application, may flush your application memory - but it is possible.

There is no absolute protection.

+2
source share

I am rewriting a comment in response :)

Even if you are not working on Azure, I still recommend using Azure Key Vault to keep your secrets. For starters, it is very cheap (about $ 0.0159 / 10,000 operations), and secondly, it can be accessed from anywhere in the world, even outside of Azure. In addition, secrets in Azure Key Vault can be versions, which is a good feature to support multiple versions of the secret for each environment (only for pre-production, since Production must have its own code). Key Vault NuGet has operations to retrieve and add secrets to .NET Core. Here is a link to the documentation.

You may have a cache in memory, so a REST call (or a call to the Key Vault package method) in Key Vault only takes place at the beginning of your application (or when your cache expires), thereby preventing further delays. Thirdly, this is Microsoft's recommended approach.

Hope this helps.

+1
source share

You don't seem to be interested in the “ways” to do this, but ASP.NET Core supports it in the recommended approach. While other answers here mentioned Azure KeyVault as a good repository for sensitive information, this is not a way to preserve it, but rather a repository. The ASP.NET kernel supports the concept of overridable configuration . That is, many configuration providers can be registered in the configuration system and in the order in which they are registered. Each registered one redefines settings from previous suppliers - those that it has, of course. In other words, if you register a standard JSON configuration provider, and then also assume that the database configuration provider, then the parameters that both providers have will receive the values ​​defined by the later provider, the database provider. So, in your situation, here is what I propose to do:

  • All registered providers have a default configuration.
  • Finally, register the Azure Key Vault configuration provider (or a similar secret storage-based storage provider).
  • Use certificate authentication for Key Vault authentication and read important settings.

Although this is not a 1: 1 mapping to your current process, it is built into the basic principles of ASP.NET.

You can learn more about ASP.NET configuration at: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/index?tabs=basicconfiguration

Here you can find out about the Azure KeyVault configuration provider: https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?tabs=aspnetcore2x

If it is not a certificate-based certificate for you, consider storing the ClientId and ClientSecret used to connect to the Azure Key storage service in environment variables and using the appropriate configuration provider ( AddEnvironmentVariables() extension method will do this) to access them.

This setting will be really safe. Good luck

+1
source share

If someone unauthorized gets access to the server, well, stealing secrets, say, database connection strings, is only a small part of the problem (@Dmitry answer).

Since you need better control over sensitive data or configuration, it is perfectly normal to deviate from the usual appsettings.json approach.

You can take secrets, encrypt them asymmetrically with a server certificate, save them in a separate file (it could be another .json file, for that matter), then read the file and decrypt the secrets at startup / on each network request. Thus, secrets are almost as secure as server certificate / private key.

Another option: symmetrically encrypt secrets and pass the password to the web application at startup so that it can decrypt the secrets. When the process on which the web application is running restarts, you must re-submit the password (you can use a separate computer to periodically submit it or so).

Also see Data Protection in the ASP.NET Kernel , Data Protective Patterns .

Sometimes long and cryptic passwords or just obfuscating a person-friendly password are enough. That is, just protecting from eavesdropping. For example, someone sitting next to the administrator will not be able to read and remember a chain of clearly random characters.

0
source share

All Articles