27

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?

Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • 1
    Duplicated question, a "more understandable" answer here: https://stackoverflow.com/a/46894509/7149454 – Nick Kovalsky May 29 '18 at 05: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 – Yodacheese Nov 01 '18 at 02:57
  • you should add Data Protection, read [this answer](https://stackoverflow.com/a/60820079/9471903) – D.L.MAN Mar 24 '20 at 07:56

5 Answers5

17

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();
    ...
}
Set
  • 47,577
  • 22
  • 132
  • 150
  • 4
    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!!! – Seabizkit Apr 30 '20 at 09:42
  • If you only need to be on one server, you can try adding `services.AddDataProtection().ProtectKeysWithDpapi();` – codeMonkey Jul 31 '20 at 00:12
  • 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 : https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-3.1#setapplicationname-1 – g4j Aug 25 '23 at 14:45
5

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>();
}
Brad
  • 71
  • 2
  • 2
  • 1
    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 – CidaoPapito Mar 26 '21 at 22:27
  • 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: https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-3.1#setapplicationname-1 – g4j Aug 25 '23 at 14:50
3

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

Carl in 't Veld
  • 1,363
  • 2
  • 14
  • 29
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); 
Damien Doumer
  • 1,991
  • 1
  • 18
  • 33
-1

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

for more information read this answer.

D.L.MAN
  • 990
  • 12
  • 18