Protecting sensitive data with data protection api

Exploring the built-in C# data protection api

Home DailyDrop

Daily Knowledge Drop

.NET has built in methods to protect and unprotected sensitive data.

These methods are typically used to protect sensitive data, but could be used to protect any data. It could also be used to expose information for a given period of time only, after which trying unprotecting the data will not work.


Configuration

There are effectively three steps to using the data protection apis:

  • Create the protector from a data protection provider
  • Invoke the Protect method to protect the data specified
  • Invoke the Unprotect method to convert the specified protected value to plain text

In the startup of the application, the protector is configured as follows:

// register base data protection
// with DI container
builder.Services
    .AddDataProtection()
    .SetDefaultKeyLifetime(TimeSpan.FromDays(7));

// register the protector with DI
builder.Services
    .AddTransient<ITimeLimitedDataProtector>(sp =>
    {
        // specify where the provider key information will be stored
        IDataProtectionProvider? provider = DataProtectionProvider
            .Create(new DirectoryInfo(@"secrets"));

        // specify the purpose string for the creator
        IDataProtector? protector = provider
            .CreateProtector("customerdata");

        return protector.ToTimeLimitedDataProtector();
    });

Some notes on the above:

  • The key information is stored in a secrets folder on the host machine. As such, the key information is only available to that one machine. If multiple machines need to access the key information, there are other storage providers available (Azure KeyVault, DbContext)
  • The protector is created with a specific purpose, customerdata above. A value protected using a specific purpose, cannot be unprotected using a different purpose value.

Protect

To protect a string, the Protect method is called. Below, an endpoint has been defined which has the ITimeLimitedDataProtector protector implementation (configured in the previous step) injected:

// get the value to protect from the route
app.MapGet("/protect/{protectValue}", (
    [FromRoute]string protectValue, 
    ITimeLimitedDataProtector protector) =>
{
    // return the protected value
    return protector.Protect(protectValue);
});

Invoking the endpoint /protect/abc123 results in the following protected value being returned:

CfDJ8BdtcMmju6ZKiKJtRHvTt2BidaZbPEirTP_KEi4-_2xVBYbs58hqVxWGQmTQBjQaO_tXTiFRAxGUPGSqXkvlfIzhd80r3AavXi0m3PiCXYfuaRhmnrzCXk6apOIqXOCvHA

Unprotect

Unprotecting is as simple as protecting a value - the Unprotect method is called, with the previously protected value supplied:

app.MapGet("/unprotect/{unprotectValue}", (
    [FromRoute] string unprotectValue, 
    ITimeLimitedDataProtector protector) =>
{
    return protector.Unprotect(unprotectValue);
});

Invoking the endpoint /unprotect/CfDJ8BdtcMmju6ZKiKJtRHvTt2BidaZbPEirTP_KEi4-_2xVBYbs58hqVxWGQmTQBjQaO_tXTiFRAxGUPGSqXkvlfIzhd80r3AavXi0m3PiCXYfuaRhmnrzCXk6apOIqXOCvHA results in the following output:

abc123

Notes

When needing to protect sensitive data (for example, authentication cookie or bearer token) this set of classes and functionality provides an easy, simple and effective way to protect the data.


References

Piotr Penza
ASP.NET Core Data Protection Overview
Configure ASP.NET Core Data Protection

Daily Drop 188: 24-10-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net dataprotector protect