Encryption and Decryption in ASP.NET Core

4.33 (6 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"));

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


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: 12373

1 Comment

- Steve

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

Recent Comments

Sivu 19/10/2016 08:21
In response to Entity Framework Core TrackGraph For Disconnected Data
Oh that's very very very nice ! Thanks for the write up Mike, much appreciated for the taking the to...

Mark 12/10/2016 16:42
In response to ASP.NET Web Pages vNext or Razor Pages
Although "Web Pages" was removed from the roadmap, has it just been renamed to "Razor Pages"?...

Satyabrata 12/10/2016 09:20
In response to Entity Framework Core TrackGraph For Disconnected Data
Nice article. Please write more articles featuring ASP.Net web pages. Thank you...

Julian 26/09/2016 14:27
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Fantastic, many thanks Mike! Had got half way down this road before finding your article - saved...

Abolfazl Roshanzamir 14/09/2016 05:36
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Nice article. Thanke you so much ....

cyrus 02/09/2016 15:12
In response to ASP.NET Web Pages vNext or Razor Pages
I've got some news. As Damian stated in this link: https://github.com/aspnet/Mvc/issues/5208 “We...

Simon 01/09/2016 08:00
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Thanks Mike, nice post and exactly what I was looking for. Like you said, I think I'll opt to the...

dave 20/08/2016 14:57
In response to ASP.NET Web Pages vNext or Razor Pages
Do SimplemembershipProvider in viewpages is supported?...

Steven 18/08/2016 04:40
In response to Entity Framework Code First and Stored Procedures
Can you provide the directives (using statements) you're using for EF7 example?...

yousaid 17/08/2016 22:08
In response to ASP.NET Web Pages vNext or Razor Pages
Increasingly, learning a Microsoft tool is no longer worth the return on investment. Too many tools...