Securing Secrets in Application Settings using .NET
Storing secrets inside configuration files is bad practice. Anyone with read access to the file can gain access to the target system, for example; a database or service.
It is far better to use a secret manager, such as Azure Key Vault, for these purposes. The application can then use a service identity which has specific rights to the secret keys in the secured vault. However, in some cases we do not have access to such systems, as when running on an isolated machine without network access. A simpler way to secure these secrets is to automatically encrypt the values within the settings file.
Background
In a previous article, I discussed using the machine key to encrypt configurations in the web.config application settings section. In this updated example, I use the same approach but update the appsettings.json file in a .NET 6 application.
The process is the same as before:
- Checks for an unencrypted value
- Encrypts the value using a salt and in the scope of the local machine account
- Saves the new encrypted value and deletes the unencrypted value
Implementation
First, I have created a configuration class and saved the data as JSON inside my appsettings.json file. I then load the settings.
I use a special object for secrets in the configuration class, named ConfigurationSecret. This class has a value and secret property, which are set using the Encrypt method. We can then return the value using the Decrypt method.
This works by using the System.Security.Cryptography.ProtectedData module.
By checking if config.Password.Value is not an empty string, we can then call the Encrypt method, which wipes the original value and sets the secret value.
I created a Save method to update the settings file using code. In my case, the settings was used within a Windows Service instance on an isolated server in a DMZ. The code module was installed as a service using remote PowerShell, the password was set initially and was encrypted immediately when the service was first started.
We will now have an encrypted value within the configuration file that is not readable.