29

In ASP.NET (not core) I would normally add a machineKey to the web.config so that I could perform some functions on a local machine instead of the server so that database/callback operations would use the same key. Eg

<system.web>
  <machineKey validationKey="*********" 
              decryptionKey="*********" 
              validation="HMACSHA256" 
              decryption="AES" />
</system.web>

Please can someone advise how this can be done in ASP.NET Core 2.0?

3
  • 1
    Duplicated question, a "more understandable" answer here: stackoverflow.com/a/46894509/7149454 Commented May 29, 2018 at 5:49
  • @pathdongle did you figure this out? I can't find any examples for Data Protection API where you can set a shared validationKey and decryptionKey Commented Nov 1, 2018 at 2:57
  • you should add Data Protection, read this answer Commented Mar 24, 2020 at 7:56

5 Answers 5

18

You need to use DataProtection APis now:

The ASP.NET Core data protection stack provide a simple, easy to use cryptographic API a developer can use to protect data, including key management and rotation.

Samples could be found in official DataProtection repo.

The same approach, by the way, works with ASP.NET: Replacing <machineKey> in ASP.NET


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) by CreateProtector method. The data protector is used to encrypt and decrypt data.

To register IDataProtectionProvider into DI use .AddDataProtection method:

public void ConfigureServices(IServiceCollection services)
{
    // Adds data protection services
    services.AddDataProtection();
    ...
}
Sign up to request clarification or add additional context in comments.

3 Comments

so is AddDataProtection all that is needed... i dnt see how that would work... surelly you have to set the key some where.... could a complete example be added plz!!!
If you only need to be on one server, you can try adding services.AddDataProtection().ProtectKeysWithDpapi();
Just to note for this, if you are using the same key across different apps (like My.App.Web and My.App.Service) you need to set a single app name : learn.microsoft.com/en-us/aspnet/core/security/data-protection/…
6

You can find good examples at https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-storage-providers?view=aspnetcore-2.2&tabs=visual-studio

I used my database context to persist the keys across multiple instances.

DbContext.cs

public class MyContext : IDataProtectionKeyContext
{
  ...
  // This maps to the table that stores keys.
  public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
  ...
  services.AddDataProtection().PersistKeysToDbContext<MyContext>();
}

2 Comments

I configured as your suggestion and the documentation but I guess I need to create the keys, equivalent to the Machine Key. How can I do that in order to have the asp.net Identity working in two different servers? Thanks
A neccessary added step was to set the ApplicaitonName for the keys so that multiple apps share the same key "the same way". If you are getting this error because the GenerateEmailConfirmationTokenAsync is called in a different app (different assembly) than ConfirmEmailAsync, you need to set the application name: learn.microsoft.com/en-us/aspnet/core/security/data-protection/…
4

For legacy purposes where you want to build out your ASP.NET Core applications based on some classic ASP.NET application that is responsible for generating the authentication cookies, there is an open source library available that enables you to consume these legacy cookies into your ASP.NET Core application. The developers have used the .NET Framework reference implementation to build their own Machinekey based encryption/decryption logic. See https://github.com/synercoder/FormsAuthentication

Comments

0

Late reply, but extremely useful to anyone willing to decrypt and encrypt FormsAuthentication ticket tokens in ASP.net core. There is a library that does just that here: https://github.com/dazinator/AspNetCore.LegacyAuthCookieCompat

Copy your validation key and decrypt key and pass it as parameters to the decrypt or encrypt functions of the library. Note that, if the decryption or encryption doesn't work right away, play with the encryption algo and the compatibility flags to match your purpose. For example:

        var encryptor = new LegacyFormsAuthenticationTicketEncryptor(SHA512DecryptionKey, SHA512ValidationKey, ShaVersion.Sha256, CompatibilityMode.Framework20SP2);

OR change the flags and compatibility to:

        var encryptor = new LegacyFormsAuthenticationTicketEncryptor(SHA512DecryptionKey, SHA512ValidationKey, ShaVersion.Sha512, CompatibilityMode.Framework45);

Then, decrypt the token as shown below:

        FormsAuthenticationTicket result = encryptor.DecryptCookie(encryptedText); 

Comments

-1

in asp.net Core you should set Data Protection system.

for more information read this answer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.