According to a recent survey by Positive Technologies, data leakage vulnerabilities and security problems affect 44% of web apps. Sensitive data is present in all web apps and data theft happens when that data is improperly secured. So, for appropriate data protection, ASP.NET Core uses cryptographic APIs, besides the encryption algorithm to protect data and avoid any data loss. Data that should not be accessible to everyone in a shared environment, can be protected using the ASP.NET Data Protection Provider.
In this blog, we will cover how the ASP.NET Data Protection Provider works and the role of NCache as a key storage provider.
Key Takeaways
Critical Problem: In Web Farm environments, default ASP.NET Core Data Protection stores keys locally, causing decryption failures when users hit different servers.
The Fix: NCache serves as a distributed key storage provider, syncing XML key rings across all servers to ensure session stability.
Security Standards: The solution supports industry-standard algorithms, including AES-256-CBC for encryption and HMACSHA256 for validation.
Easy Implementation: Developers can enable this by installing the AspNetCore.DataProtection.NCache NuGet package and calling .PersistKeysToNCache() in Startup.cs.
ASP.NET Core Data Protection Provider
Data Protection is a feature of ASP.NET Core that enables you to secure your data using various encryption methods. The system relies on industry-standard encryption algorithms to ensure both security and integrity:
- AES-256-CBC: Used for confidentiality (encryption).
- HMACSHA256: Used for authenticity (validation).
- Master Key: A 512-bit key rolled over every 90 days.
The two sub-keys essential for these methods are derived from this master key, which is modified every 90 days per payload..
|
1 2 3 |
services.AddDataProtection() // use a 14-day lifetime instead of a 90-day lifetime .SetDefaultKeyLifetime(TimeSpan.FromDays(14)); |
The key generated is stored/persisted using key storage providers.
Key Storage providers
The data protection system employs a default discovery mechanism to determine where the cryptographic keys should persist. The developer can override the default discovery mechanism and manually specify the location.
1. Default key storage provider
By default, the keys persist in a specified temp folder in windows in ASP.NET Core, but storing the keys in the default location has a drawback – keys are not accessible by multiple web application instances. So, to make keys available across multiple servers and accessible by all web application instances, the user must manually specify a location for key persistence.
2. NCache as a key storage provider
To make keys available across multiple servers, ASP.NET Core enables you to configure your key storage provider. Here we can use NCache as a key storage provider, the keys persist in a cache, and since NCache is a cluster-wide shared cache, this makes keys available to all web application instances. Using the method, PersistKeysToNCache.
- PersistKeysToNCache
PersistKeysToNCache is the entry point where the user can specify the cache name and cache tag where the keys will persist while configuring NCache as a key storage provider.
How to Configure NCache as a key storage provider
NCache works as a key storage provider to store the keys for data protection services, and its configuration is simple and easy. To configure NCache ASP.NET Core Data Protection Provider, follow the steps below.
Step 1: Configure Data Protection Service
ASP.NET Core provides middleware for Data Protection. This middleware has to be added to the service collection using the AddDataProtection() method. Provide DirectoryInfo pointing to the repository where keys should be stored.
-
- Open the
startup.csfile of your project. To enable data protection, you must register the Data Protection services with the application’s dependency injection container. This sets up the cryptographic infrastructure required to secure sensitive payloads.
- Open the
- In the
ConfigureServices()method, add the following service:
|
1 2 3 4 5 |
public void ConfigureServices(IServiceCollection services) { // Adds Data Protection services to the dependency injection container services.AddDataProtection(); } |
Step 2: Install the NuGet Package
The first step is to install the NuGet package that allows sharing ASP.NET Core Data Protection keys in NCache. To install the NuGet package, first open Visual Studio and go to Tools -> NuGet Package Manager -> Package Manager Console and then search for the NuGet package AspNetCore.DataProtection.NCache.
Step 3: Configure NCache as a key storage provider for the Data Protection service
After installing the NuGet package, first you’ve to configure NCache as a key storage provider to store keys for data protection services.
|
1 2 3 4 5 6 7 |
public void ConfigureServices(IServiceCollection services) { string cacheName = "demoCache"; string cacheTag = "encryptions_keys_tag"; // Configures NCache as the external key storage provider services.AddDataProtection().PersistKeysToNCache(cacheName, cacheTag); } |
To further use NCache as a key storage provider in ASP.NET Core data protection provider, implement the sample application below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.AspNetCore.DataProtection; using Alachisoft.NCache.AspNetCore.DataProtection; namespace DataProtectionSample { public class Program { static void Main(string[] args) { string cacheName = "demoLocalCache"; string cacheTag = "MyEncryptionKeys"; var serviceCollection = new ServiceCollection(); serviceCollection.AddDataProtection() .PersistKeysToNCache(cacheName,cacheTag); var services = serviceCollection.BuildServiceProvider(); // create an instance of MyClass using the service provider var instance = ActivatorUtilities.CreateInstance(services); instance.RunSample(); } } Public class MyClass { IDataProtector _protector; // the 'provider' parameter is provided by DI public MyClass(IDataProtectionProvider provider) { _protector = provider.CreateProtector("Contoso.MyClass.v1"); } public void RunSample() { Console.Write("Enter input: "); string input = Console.ReadLine(); // protect the payload string protectedPayload = _protector.Protect(input); Console.WriteLine($"Protect returned: {protectedPayload}"); // unprotect the payload string unprotectedPayload = _protector.Unprotect(protectedPayload); Console.WriteLine($"Unprotect returned: {unprotectedPayload}"); } } } |
Conclusion
ASP.NET Core ensures that the added data is secure by using cryptographic APIs in addition to encryption algorithms, which are equally important. Essentially, NCache acts as a key storage provider to store keys and then makes them accessible by multiple web application instances. So, download a fully working 60-day trial now, and use it yourself.
Frequently Asked Questions (FAQ)
Q: Why is external key storage required for ASP.NET Core Data Protection?
A: External key storage is necessary in load-balanced (Web Farm) environments because the default local storage prevents servers from sharing cryptographic keys. If keys are not shared, a user session created on Server A cannot be decrypted by Server B, leading to data loss or logout errors.
Q: How does NCache function as a Key Storage Provider?
A: NCache acts as a centralized, distributed repository that persists XML key rings. By using the PersistKeysToNCache method, NCache ensures that all web application instances in the cluster have instant access to the same active master keys.
Q: What specific algorithms does ASP.NET Core Data Protection use?
A: By default, the system uses AES-256-CBC for confidentiality (encrypting the payload) and HMACSHA256 for authenticity (verifying the payload has not been tampered with).
Q: How do I configure NCache for Data Protection in .NET?
A: You configure NCache by adding the AspNetCore.DataProtection.NCache NuGet package and modifying the ConfigureServices method in your Startup.cs file to include: services.AddDataProtection().PersistKeysToNCache(cacheName, cacheTag);







Great information. Thanks for sharing