Skip to content
This repository was archived by the owner on Oct 17, 2018. It is now read-only.
This repository was archived by the owner on Oct 17, 2018. It is now read-only.

Cannot unprotect data after upgrading .NET Framework app to new DataProtection version #187

Closed
@nphmuller

Description

@nphmuller

An exception is thrown when I try to unprotect data in release 1.1.0 which was protected with release 1.0.0. This only happens when I target the full .Net Framework stack (only tested net462). When I target netcoreapp everything runs smoothly.

Seems like there are some differences between .Net Full and .Net Core in the way library versions are bound. In issue #153 almost the same problem happens.

These are the exception details:

System.Security.Cryptography.CryptographicException was unhandled
  HResult=-2146233296
  Message=The provided payload could not be decrypted. Refer to the inner exception for more information.
  Source=Microsoft.AspNetCore.DataProtection
  StackTrace:
       at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
       at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked)
       at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
       at Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.Unprotect(IDataProtector protector, String protectedData)
       at ConsoleApp2.Program.Main(String[] args) in c:\users\mulle\documents\visual studio 2015\Projects\ConsoleApp2\src\ConsoleApp2\Program.cs:line 20
  InnerException: 
       FileName=Microsoft.AspNetCore.DataProtection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
       FusionLog==== Pre-bind state information ===
LOG: DisplayName = Microsoft.AspNetCore.DataProtection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 (Fully-specified)
LOG: Appbase = file:///c:/users/mulle/documents/visual studio 2015/Projects/ConsoleApp2/src/ConsoleApp2/bin/Debug/net462/win7-x64/
LOG: Initial PrivatePath = NULL
Calling assembly : Microsoft.AspNetCore.DataProtection, Version=1.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: c:\users\mulle\documents\visual studio 2015\Projects\ConsoleApp2\src\ConsoleApp2\bin\Debug\net462\win7-x64\ConsoleApp2.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Microsoft.AspNetCore.DataProtection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
LOG: Attempting download of new URL file:///c:/users/mulle/documents/visual studio 2015/Projects/ConsoleApp2/src/ConsoleApp2/bin/Debug/net462/win7-x64/Microsoft.AspNetCore.DataProtection.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Minor Version
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.

       HResult=-2146234304
       Message=Could not load file or assembly 'Microsoft.AspNetCore.DataProtection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
       Source=mscorlib
       StackTrace:
            at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type)
            at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
            at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
            at System.Type.GetType(String typeName, Boolean throwOnError)
            at Microsoft.AspNetCore.DataProtection.SimpleActivator.CreateInstance(Type expectedBaseType, String implementationTypeName)
            at Microsoft.AspNetCore.DataProtection.ActivatorExtensions.CreateInstance[T](IActivator activator, String implementationTypeName)
            at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
            at Microsoft.AspNetCore.DataProtection.KeyManagement.DeferredKey.<>c__DisplayClass1_0.<GetLazyEncryptorDelegate>b__0()
            at System.Lazy`1.CreateValue()
            at System.Lazy`1.LazyInitValue()
            at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRing.KeyHolder.GetEncryptorInstance(Boolean& isRevoked)
            at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRing.GetAuthenticatedEncryptorByKeyId(Guid keyId, Boolean& isRevoked)
            at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
       InnerException: 

I wrote a small app that demonstrates my problem:

project.json:

{
  "version": "1.0.0-*",
  "buildOptions": {
    "emitEntryPoint": true
  },

  "dependencies": {
    "Microsoft.AspNetCore.DataProtection.Extensions": "1.1.0"
  },

  "frameworks": {
    "net462": {
      "dependencies": {
        "System.Reflection": "4.*",
        "System.Runtime": "4.*",
        "System.Runtime.Extensions": "4.*"
      }
    } 
  }
}

Program.cs:

using System;
using System.IO;
using Microsoft.AspNetCore.DataProtection;

namespace ConsoleApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var keysDir = new DirectoryInfo(Environment.ExpandEnvironmentVariables(@"%localappdata%\ASP.NET\DataProtection-Keys"));
            var protector = DataProtectionProvider.Create(keysDir).CreateProtector("Test");

            string protectedData;
            // The commented line was ran with "Microsoft.AspNetCore.DataProtection.Extensions" on version 1.0.0 in project.json.
            // This was used to create the protected data used in the line below it.
            //protectedData = protector.Protect("TestData");
            protectedData = "CfDJ8Hfj9GhtU4RDpuGkMJ0qEoKKKVc2uSFps_1jM0HoQKiXD8ii6UrKRFQ2YzMhm7pHLtFlKWk7XhJymmxCb1Ci7p2d34I-1VAn7xQgkMTAUKmi_Td11UXfN3FARidrfzL6IA";

            //The exception is thrown on this line:
            var unprotectedData = protector.Unprotect(protectedData);
        }
    }
}

And the key file (key-68f4e377-536d-4384-a6e1-a4309d2a1282.xml).
Place it in '%LocalAppData%\ASP.NET\DataProtection-Keys' (or change the line of code).
Don't worry, the key was created only for this issue ;)

<?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>

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions