Encryption and Decryption in ASP.NET Core

4.3 (10 votes)

The ASP.NET Core framework provides a new API for protecting data, including mechanisms for encryption and decryption. This article takes a quick look at how they can be used.

Difference between Encoding, Encryption and Hashing

First, I want to quickly go over some basics so you can make the right choice, particularly when it comes to managing passwords securely. I have seen articles purportedly about encrypting passwords in ASP.NET that show how to Base-64 encode and decode a string. Encoding data is not a security measure - even if the resulting output is unreadable to humans. Encoding data simply provides protection against data corruption when transferring that data from one place to another, such as across networks.

Encryption is similar to encoding in that it is designed to be reversible. However, encryption uses a cryptographic algorithm to convert the data from one form to another, and only those with access to a particular cryptographic key are able to unscramble it back to its original form.

Finally, there is hashing, which shares a reliance on cryptography with encryption, but is a one-way process. Data that has been properly hashed cannot be unhashed or decoded. Hashing is typically recommended for secure storage of passwords, and is used by all the Identity/Membership frameworks in .NET. When a user registers with a web site, the password they provide is hashed and then the hashed value is stored in the database. When they attempt to log in subsequently, the password they provide is hashed, and the newly hashed value is compared to the one that has already been stored. Hashing is deterministic in that it always produces the same result, given the same input.

Data Protection APIs in ASP.NET Core

The data protection APIs provide mechanisms for encryption and hashing but this article is only concerned with encryption. Encryption requires a key, which is created and managed by the data protection system. Keys are created with a default lifetime of 90 days, and stored in a suitable location according to the environment. Keys are temporary, so the data protection API is designed mainly for short term data protection scenarios such as encryption of authentication cookies or query string data. It is not designed for the protection of data that, for example, might be stored long term in a database.

The data protection system is enabled as part of the default services for an ASP.NET Core application, so you do not need to do anything in your StartUp method unless you want to reconfigure the default key storage location or the life time of keys. If that is the case, you can use the ConfigureDataProtection extension method in the ConfigureServices method:

public void ConfigureServices(IServiceCollection services)
{
    services.ConfigureDataProtection(dp =>
    {
        dp.PersistKeysToFileSystem(new DirectoryInfo(@"c:\keys"));
        dp.SetDefaultKeyLifetime(TimeSpan.FromDays(14));
    });
    ....

The data protection system is built upon two core concepts - a data protection provider (represented by the IDataProtectionProvider interface), which is used to create a data protector (represented by the IDataProtector interface). The data protector is used to encrypt and decrypt data. Because the data protection system has been added to the application's services collection by default, it can be made available via dependency injection. Here's how you can inject the IDataProtectionProvider into a controller and then use it to create an instance of an IDataProtector in the controller's constructor:

public class HomeController : Controller
{
    IDataProtector _protector;
        
    public HomeController(IDataProtectionProvider provider)
    {
        _protector = provider.CreateProtector(GetType().FullName);
    }

The CreateProtector method of the IDataProtectionProvider requires a string, known as a "purpose" string. This is used to differentiate one data protector from another in the same application. Data that has been protected by one data protector cannot be unprotected by a different protector. The recommendation is that you pass in the fully qualified name of the current component as this won't conflict with protectors instantiated in other parts of the system.

Encrypting Query Strings/Route Data

One of the most frequent encryption scenarios that I see questions about is in the realm of encrypting identity values in query strings or route data to prevent tampering, and potential access to restricted data. The following section of code illustrates getting some data from a service, and then transforming that data to a view model while encrypting the ID of each item for use in a URL:

public IActionResult Index()
{
    var model = _service.GetAll().Select(c => new ContractViewModel {
        Id = _protector.Protect(c.Id.ToString()),
        Name = c.Name }).ToList();
    return View(model);
}

The Protect method takes a byte array or a string, and encrypts it. The encrypted value is then used in the view to form the Id parameter of a route:

@foreach(var entry in Model)
{
    <div><a asp-action="Details" asp-route-id="@entry.Id">@entry.Name</a></div>
}

Data Protection ASP.NET Core

The links point to an action named Details, where the IDataProtector's Unprotect method is used to decrypt the Id parameter and retrieve details of the selected item:

public IActionResult Details(string id)
{
    var contract = _service.Find(Convert.ToInt32(_protector.Unprotect(id)));
    return View(contract);
}

You can see the encrypted value in the URL when any of the links are clicked:

Data Protection ASP.NET Core

Summary

This article provides an introduction to the Data Protection system that has been built from the ground up for use with ASP.NET Core applications. It began with a refresher on the differences between encoding, encryption and hashing, and when you might want to use each process. Then it described the core concepts on which the encryption/decryption system is built and how to use the components to securely encrypt and decrypt data.

Even though it is still at RC 1 stage at the time of writing, the documentation for the Data Protection APIs is quite comprehensive, and is well worth a read at https://docs.asp.net/en/latest/security/data-protection/index.html.

You might also like...

Date Posted:
Last Updated:
Posted by:
Total Views to date: 20729

1 Comment

- Steve

A very informative, well-written article. Thank you very much.

Recent Comments

Cyrus 16/05/2017 19:55
In response to Razor Pages - Getting Started With The Preview
There is something wrong related to microsoft.dotnetcore.mvc.taghelpers! if you remove it from page...

Cyrus 16/05/2017 10:18
In response to Razor Pages - Getting Started With The Preview
well done mike, it was very useful, I really appreciate that....

Satyabrata Mohapatra 16/05/2017 07:21
In response to Razor Pages - Getting Started With The Preview
Finally!!!! web pages in asp.net core!!! Super excited !!!! Thank u sir for sharing.....Awaiting on...

Daniele 14/03/2017 10:24
In response to Working With Zip Files In ASP.NET MVC
is it possible give to the user a progress bar of the zipping process? Thanks in advance. ...

Suraj 13/03/2017 22:20
In response to Working With Zip Files In ASP.NET MVC
Very nice article. Thanks....

Satyabrata Mohapatra 19/02/2017 03:01
In response to Free SSL Certificates On IIS With LetsEncrypt
Thanks for sharing. Learned a lot !!...

Gfw 03/02/2017 09:48
In response to Free SSL Certificates On IIS With LetsEncrypt
I have used WinSimple for about the last 9 months - works great. One thing that you want to make of...

Ted Driver 02/02/2017 13:24
In response to Free SSL Certificates On IIS With LetsEncrypt
This looks great is you have command line access to your web server - what about those of us on Is...

Aghil 16/11/2016 18:16
In response to Server.MapPath Equivalent in ASP.NET Core
Hi, Thanks, it was really good. However, how can we access the in the Classes? Is there any...

Carl T. 06/11/2016 05:43
In response to Server.MapPath Equivalent in ASP.NET Core
Very succinct and easy to follow. Worked perfectly the first time for me. Thanks!!...