Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataProtection AuthenticatedEncryptorDescriptorDeserializer version missmatch #3255

Closed
oliverluethi opened this issue Jun 22, 2018 · 9 comments
Labels
area-dataprotection Includes: DataProtection bug This issue describes a behavior which is not expected - a bug. ✔️ Resolution: Won't Fix Resolved because we decided not to change the behavior reported in this issue.

Comments

@oliverluethi
Copy link

oliverluethi commented Jun 22, 2018

Hi there...

I'm using the NugetPackages "Microsoft.AspNetCore.DataProtection 2.1.1" and "Microsoft.AspNetCore.DataProtection.Extensions 2.1.1" in a .NET Standard 2.0 library.

Initializing of the DataProtectionProvider and Protector

var destFolder = Path.Combine(System.Environment.GetEnvironmentVariable("LOCALAPPDATA"),"myKeys");
            provider = DataProtectionProvider.Create(
                new DirectoryInfo(destFolder));
            _protector = provider.CreateProtector("MyCache");
        }

If I try to protect a plain string var encrypted = _protector.Protect(json); I get the following message:

The type 'Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' is not assignable to 'Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.IAuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.

Maybe I'm doing something wrong here?

@Tratcher
Copy link
Member

Your dependencies are misaligned, you're trying to reference 1.0.2.0 and 2.1.1.0 of the same package.

@oliverluethi
Copy link
Author

@Tratcher Yes, I see this. After some more investigation I saw that the .NET Standard Library works fine with a clean ConsoleApp project, but fails with an AzureFunctions project. I don't see any reference of a DataProtection library in the AzureFunctions project, but it seems there is something which causes this problem.

@Eilon
Copy link
Member

Eilon commented Jul 13, 2018

@oliverluethi - were you able to resolve the issue? If not, please upload a repro project to GitHub (in a new repo, or a ZIP) so that we can investigate. Thanks!

@oliverluethi
Copy link
Author

@Eilon No, error still exists. I'll upload a sample project shortly, Thanks!

@oliverluethi
Copy link
Author

@Eilon Here is a sample project, thanks for your help!
FunctionApp1.zip

@Eilon Eilon added the area-dataprotection Includes: DataProtection label Jul 18, 2018
@natemcmaster natemcmaster self-assigned this Aug 31, 2018
@natemcmaster
Copy link
Contributor

I can reproduce the problem. I'll describe the details below.

fails with an AzureFunctions project.

This is the key to the problem. In Azure Functions v1, the Azure Functions host has a dependency on DataProtection 1.0.2. This causes some goofy behaviors when deserializing an XML key, such as the one below. As you can see, the key defines a type that should be used for deserializing the key content.

<?xml version="1.0" encoding="utf-8"?>
<key id="68f4e377-536d-4384-a6e1-a4309d2a1282" version="1">
  <creationDate>2016-11-23T21:37:00.3045352Z</creationDate>
  <activationDate>2016-11-23T21:37:00.2025208Z</activationDate>
  <expirationDate>2017-02-21T21:37:00.2025208Z</expirationDate>
  <descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
    <descriptor>
      <encryption algorithm="AES_256_CBC" />
      <validation algorithm="HMACSHA256" />
      <masterKey p4:requiresEncryption="true" xmlns:p4="http://schemas.asp.net/2015/03/dataProtection">
        <!-- Warning: the key below is in an unencrypted form. -->
        <value>rA5uDx7kFHrx0Qt+owWotP0NQf/wBxL/breAbCh+AOVjrdGHca5hgIIuQIlyBFlXB/X1pXj6tL40JwQ6iUD43Q==</value>
      </masterKey>
    </descriptor>
  </descriptor>
</key>

When DataProtection is reading this file, it strips the version from this assembly-qualified type name (due to aspnet/DataProtection#223) and calls Type.GetType(string).

Type.GetType("Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Culture=neutral, PublicKeyToken=adb9793829ddae60");

The AzureFunctions host process has two versions of a type that match this type, and returns the first one it finds. In Azure Functions, this returns the version the host provides, not the version the function wants. In this case, it causes a type mismatch because IAuthenticatedEncryptorDescriptorDeserializer (v1) != IAuthenticatedEncryptorDescriptorDeserializer (v2). You can reproduce this in an Azure Function like this:

var actualType = Type.GetType("Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Culture=neutral, PublicKeyToken=adb9793829ddae60");
vvar expectedType = typeof(AuthenticatedEncryptorDescriptorDeserializer);

return req.CreateResponse(HttpStatusCode.OK, $"Actual = {actualType?.AssemblyQualifiedName}\r\nExpected = {expectedType.AssemblyQualifiedName}");

Actual = Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=1.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
Expected = Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60

@natemcmaster natemcmaster added bug This issue describes a behavior which is not expected - a bug. and removed investigate labels Oct 2, 2018
@natemcmaster
Copy link
Contributor

To solve this, we need a fix to https://github.com/aspnet/DataProtection/blob/master/src/Microsoft.AspNetCore.DataProtection/TypeForwardingActivator.cs which understands that multiple versions of an assembly may exist in a .NET app, and has a way to determine correctly which one should be used.

The only simple solution I can think of right now is one that keeps a list of well-known data protection assemblies, and attempts to resolve types against those assemblies before falling back to Type.GetType.

@muratg muratg assigned pakrym and unassigned natemcmaster Oct 10, 2018
@muratg muratg added this to the 2.2.0-preview3 milestone Oct 10, 2018
@muratg
Copy link
Contributor

muratg commented Oct 10, 2018

@pakrym if we can't fit the fix in preview3, we can punt this.

@muratg muratg modified the milestones: 2.2.0-preview3, 2.2.0 Oct 11, 2018
@muratg muratg removed this from the 2.2.0 milestone Oct 19, 2018
@muratg muratg added the ✔️ Resolution: Won't Fix Resolved because we decided not to change the behavior reported in this issue. label Oct 19, 2018
@muratg
Copy link
Contributor

muratg commented Oct 19, 2018

We won't be fixing this in DataProtection in 2.2

Recommendation is to move to Azure Functions V2. (Or if you have to work on V1, consider moving to .NET Core.)

@muratg muratg closed this as completed Oct 19, 2018
@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-dataprotection Includes: DataProtection bug This issue describes a behavior which is not expected - a bug. ✔️ Resolution: Won't Fix Resolved because we decided not to change the behavior reported in this issue.
Projects
None yet
Development

No branches or pull requests

6 participants