Fededim.Extensions.Configuration.Protected
1.0.0
Prefix Reserved
See the version list below for details.
dotnet add package Fededim.Extensions.Configuration.Protected --version 1.0.0
NuGet\Install-Package Fededim.Extensions.Configuration.Protected -Version 1.0.0
<PackageReference Include="Fededim.Extensions.Configuration.Protected" Version="1.0.0" />
paket add Fededim.Extensions.Configuration.Protected --version 1.0.0
#r "nuget: Fededim.Extensions.Configuration.Protected, 1.0.0"
// Install Fededim.Extensions.Configuration.Protected as a Cake Addin #addin nuget:?package=Fededim.Extensions.Configuration.Protected&version=1.0.0 // Install Fededim.Extensions.Configuration.Protected as a Cake Tool #tool nuget:?package=Fededim.Extensions.Configuration.Protected&version=1.0.0
About
Fededim.Extensions.Configuration.Protected is an improved ConfigurationBuilder which allows partial or full encryption of configuration values stored inside any possible ConfigurationSource and fully integrated in the ASP.NET Core architecture. Basically, it implements a custom ConfigurationBuilder and a custom ConfigurationProvider defining a custom tokenization tag which whenever found decrypts the enclosed encrypted data using ASP.NET Core Data Protection API.
Key Features
- Encrypt partially or fully a configuration value
- Works with any existant and (hopefully) future ConfigurationSource and ConfigurationProvider (tested with CommandLine, EnvironmentVariables, Json, Xml and InMemoryCollection)
- Trasparent in memory decryption of encrypted values without almost any additional line of code
- Supports a global ConfigurationBuilder configuration and an eventual custom override for any ConfigurationSource
- Supports almost any NET framework (net6.0, netstandard2.0 and net462)
- Pluggable into any project with almost no changes to original NET / NET Core.
How to Use
- Modify the configuration sources by enclosing with the encryption tokenization tag (e.g. Protect:{<data to be encrypted}) all the values or part of values you would like to encrypt
- Configure the data protection api in a helper method (e.g. ConfigureDataProtection)
- Encrypt all appsettings values by calling IDataProtect.ProtectFiles, IDataProtect.ProtectConfigurationValue and IDataProtect.ProtectEnvironmentVariables extension methods (use ProtectedConfigurationBuilder.DataProtectionPurpose as CreateProtector purpose)
- Define the application configuration using ProtectedConfigurationBuilder and adding any standard framework provided or custom configuration source
- Call ProtectedConfigurationBuilder.Build to automatically decrypt the encrypted values and retrieve the cleartext ones into a IConfigurationRoot class.
- Map the Configuration object to a strongly typed hierarchical class using DI Configure
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel;
using Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption;
using Fededim.Extensions.Configuration.Protected.ConsoleTest;
using Microsoft.Extensions.Options;
using Fededim.Extensions.Configuration.Protected;
using System.Diagnostics;
using System;
using System.Collections.Generic;
using System.IO;
public class Program
{
private static void ConfigureDataProtection(IDataProtectionBuilder builder)
{
builder.UseCryptographicAlgorithms(new AuthenticatedEncryptorConfiguration
{
EncryptionAlgorithm = EncryptionAlgorithm.AES_256_CBC,
ValidationAlgorithm = ValidationAlgorithm.HMACSHA256,
}).SetDefaultKeyLifetime(TimeSpan.FromDays(365 * 15)).PersistKeysToFileSystem(new DirectoryInfo("..\\..\\..\\Keys"));
}
public static void Main(String[] args)
{
args = new String[] { "--password Protect:{secretArgPassword!}" };
// define the DI services: setup Data Protection API
var servicesDataProtection = new ServiceCollection();
ConfigureDataProtection(servicesDataProtection.AddDataProtection());
var serviceProviderDataProtection = servicesDataProtection.BuildServiceProvider();
// define the DI services: setup a Data Protection API custom tailored for a particular providers (InMemory and Environment Variables)
// retrieve IDataProtector interfaces for encrypting data
var dataProtector = serviceProviderDataProtection.GetRequiredService<IDataProtectionProvider>().CreateProtector(ProtectedConfigurationBuilder.DataProtectionPurpose());
var dataProtectorAdditional = serviceProviderDataProtection.GetRequiredService<IDataProtectionProvider>().CreateProtector(ProtectedConfigurationBuilder.DataProtectionPurpose(2));
// define in-memory configuration key-value pairs to be encrypted
var memoryConfiguration = new Dictionary<String, String>
{
["SecretKey"] = "Protect:{InMemory MyKey Value}",
["TransientFaultHandlingOptions:Enabled"] = bool.FalseString,
["Logging:LogLevel:Default"] = "Protect:{Warning}"
};
// define an environment variable to be encrypted
Environment.SetEnvironmentVariable("SecretEnvironmentPassword", "Protect:{SecretEnvPassword!}");
// encrypts all configuration sources (must be done before reading the configuration)
// encrypts all Protect:{<data>} token tags inside command line argument (you can use also the same method to encrypt String, IEnumerable<String>, IDictionary<String,String> value of any configuration source
var encryptedArgs = dataProtector.ProtectConfigurationValue(args);
// encrypts all Protect:{<data>} token tags inside im-memory dictionary
dataProtectorAdditional.ProtectConfigurationValue(memoryConfiguration);
// encrypts all Protect:{<data>} token tags inside .json files and all OtherProtect:{<data>} inside .xml files
var encryptedJsonFiles = dataProtector.ProtectFiles(".");
var encryptedXmlFiles = dataProtector.ProtectFiles(".", searchPattern: "*.xml", protectRegexString: "OtherProtect:{(?<protectData>.+?)}", protectedReplaceString: "OtherProtected:{${protectedData}}");
// encrypts all Protect:{<data>} token tags inside environment variables
dataProtectorAdditional.ProtectEnvironmentVariables();
// please check that all configuration source defined above are encrypted (check also Environment.GetEnvironmentVariable("SecretEnvironmentPassword") in Watch window)
Debugger.Break();
// define the application configuration using almost all possible known ConfigurationSources
var configuration = new ProtectedConfigurationBuilder(dataProtectionServiceProvider: serviceProviderDataProtection)
.AddCommandLine(encryptedArgs)
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNETCORE_ENVIRONMENT")}.json")
.AddXmlFile("appsettings.xml").WithProtectedConfigurationOptions(protectedRegexString: "OtherProtected:{(?<protectedData>.+?)}")
.AddInMemoryCollection(memoryConfiguration).WithProtectedConfigurationOptions(dataProtectionServiceProvider: serviceProviderDataProtection, keyNumber: 2)
.AddEnvironmentVariables().WithProtectedConfigurationOptions(dataProtectionServiceProvider: serviceProviderDataProtection, keyNumber: 2)
.Build();
// define other DI services: configure strongly typed AppSettings configuration class (must be done after having read the configuration)
var services = new ServiceCollection();
services.Configure<AppSettings>(configuration);
var serviceProvider = services.BuildServiceProvider();
// retrieve the strongly typed AppSettings configuration class
var appSettings = serviceProvider.GetRequiredService<IOptions<AppSettings>>().Value;
// please check that all values inside appSettings class are actually decrypted with the right value.
Debugger.Break();
}
}
The main types provided by this library are:
- Fededim.Extensions.Configuration.Protected.ProtectedConfigurationBuilder
- Fededim.Extensions.Configuration.Protected.ProtectedConfigurationProvider
- Fededim.Extensions.Configuration.Protected.ProtectedConfigurationData
Feedback & Contributing
Fededim.Extensions.Configuration.Protected is released as open source under the MIT license. Bug reports and contributions are welcome at the GitHub repository.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- Microsoft.AspNetCore.DataProtection (>= 8.0.0)
- Microsoft.Extensions.Configuration (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection (>= 8.0.0)
- System.CodeDom (>= 8.0.0)
-
.NETStandard 2.0
- Microsoft.AspNetCore.DataProtection (>= 8.0.0)
- Microsoft.Extensions.Configuration (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection (>= 8.0.0)
- System.CodeDom (>= 8.0.0)
-
net6.0
- Microsoft.AspNetCore.DataProtection (>= 8.0.0)
- Microsoft.Extensions.Configuration (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection (>= 8.0.0)
- System.CodeDom (>= 8.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Fededim.Extensions.Configuration.Protected:
Package | Downloads |
---|---|
Fededim.Extensions.Configuration.Protected.DataProtectionAPI
Fededim.Extensions.Configuration.Protected.DataProtectionAPI is the standard Microsoft DataProtectionAPI provider for the encryption/decryption of configuration values using Fededim.Extensions.Configuration.Protected. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.19 | 131 | 10/9/2024 |
1.0.18 | 133 | 7/29/2024 |
1.0.17 | 268 | 7/3/2024 |
1.0.16 | 139 | 6/28/2024 |
1.0.15 | 140 | 6/27/2024 |
1.0.14 | 131 | 6/26/2024 |
1.0.13 | 161 | 6/17/2024 |
1.0.12 | 154 | 6/15/2024 |
1.0.11 | 104 | 6/5/2024 |
1.0.10 | 96 | 6/3/2024 |
1.0.9 | 99 | 5/30/2024 |
1.0.8 | 96 | 5/30/2024 |
1.0.7 | 120 | 5/8/2024 |
1.0.6 | 123 | 4/26/2024 |
1.0.5 | 163 | 2/7/2024 |
1.0.4 | 107 | 2/7/2024 |
1.0.3 | 198 | 1/1/2024 |
1.0.2 | 133 | 1/1/2024 |
1.0.1 | 155 | 12/16/2023 |
1.0.0 | 119 | 12/15/2023 |
v1.0.0
- Initial commit:
- Known limitations: it does not support ReloadOnChange for FileConfigurationProviders, the code needs to be refactored to switch from composition to dynamically create at runtime using Codedom a new type derived from an existing IConfigurationProvider which overrides the Load method with the decryption function. It everything works out, it will be done in the next release.