title: How to protect data protection key files with a certificate on Asp.Net Core 2 on debian/linux
body: <p>I'm trying to configuring data protection and to use the certificate to protect key files. Here is the MS documentation <a href="https://docs.microsoft.com/fr-fr/aspnet/core/security/data-protection/configuration/overview?tabs=aspnetcore2x" rel="noreferrer">Configuring data protection</a></p>
  
  <p>Here is what I'm trying to do:</p>
  
  <pre><code>services
      .AddDataProtection()
      .SetApplicationName("test server")
      .PersistKeysToFileSystem("/home/www-data/config")
      .ProtectKeysWithCertificate(
          new X509Certificate2("/home/www-data/config/"keyprotection.pfx);
  </code></pre>
  
  <p>When I launch the application I get the following error on startup:</p>
  
  <pre><code>info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58]
      Creating key {71e2c23f-448b-49c9-984f-3c8d7227c904} with 
      creation date 2017-08-29 18:53:51Z, activation date 2017-08-29 18:53:51Z, and expiration date 2017-11-27 18:53:51Z.
  info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39]
      Writing data to file '/home/www-data/config/key-71e2c23f-448b-49c9-984f-3c8d7227c904.xml'.
  fail: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[24]
      An exception occurred while processing the key element '&lt;key id="71e2c23f-448b-49c9-984f-3c8d7227c904" version="1" /&gt;'.
  System.Security.Cryptography.CryptographicException: Unable to retrieve the decryption key.
      at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri)
      at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument()
      at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.Decrypt(XElement encryptedElement)
      at Microsoft.AspNetCore.DataProtection.XmlEncryption.XmlEncryptionExtensions.DecryptElement(XElement element, IActivator activator)
      at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
  warn: Microsoft.AspNetCore.DataProtection.KeyManagement.DefaultKeyResolver[12]
      Key {71e2c23f-448b-49c9-984f-3c8d7227c904} is ineligible to be the default key because its CreateEncryptor method failed.
  System.Security.Cryptography.CryptographicException: Unable to retrieve the decryption key.
      at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri)
      at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument()
      at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.Decrypt(XElement encryptedElement)
      at Microsoft.AspNetCore.DataProtection.XmlEncryption.XmlEncryptionExtensions.DecryptElement(XElement element, IActivator activator)
      at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
      at Microsoft.AspNetCore.DataProtection.KeyManagement.DeferredKey.&lt;&gt;c__DisplayClass1_0.&lt;GetLazyDescriptorDelegate&gt;b__0()
      at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
      at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
      at System.Lazy`1.CreateValue()
      at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyBase.get_Descriptor()
      at Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.CngGcmAuthenticatedEncryptorFactory.CreateEncryptorInstance(IKey key)
      at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyBase.CreateEncryptor()
      at Microsoft.AspNetCore.DataProtection.KeyManagement.DefaultKeyResolver.CanCreateAuthenticatedEncryptor(IKey key)
  warn: Microsoft.AspNetCore.DataProtection.KeyManagement.DefaultKeyResolver[12]
      Key {71e2c23f-448b-49c9-984f-3c8d7227c904} is ineligible to be the default key because its CreateEncryptor method failed.
  System.Security.Cryptography.CryptographicException: Unable to retrieve the decryption key.
      at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri)
      at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument()
      at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.Decrypt(XElement encryptedElement)
      at Microsoft.AspNetCore.DataProtection.XmlEncryption.XmlEncryptionExtensions.DecryptElement(XElement element, IActivator activator)
      at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
      at Microsoft.AspNetCore.DataProtection.KeyManagement.DeferredKey.&lt;&gt;c__DisplayClass1_0.&lt;GetLazyDescriptorDelegate&gt;b__0()
      at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
  --- End of stack trace from previous location where exception was thrown ---
  </code></pre>
  
  <p>So the key is created and well encrypted. But it seems that somehow it doesn't know how to decrypt it as it says in the error:</p>
  
  <pre><code>System.Security.Cryptography.CryptographicException: 
      Unable to retrieve the decryption key.
  </code></pre>
  
  <p>If I understand it correctly, it uses the certificate I provided to encrypt the key. But it looks like it doesn't use the same cert for the decryption for some reason (It looks like it tries to retreive it from somewhere else [store?]).</p>
  
  <p>What is going wrong ?</p>
  
  <p>I also tried to put the cert into CA store as described here:
  <a href="https://www.humankode.com/asp-net-core/develop-locally-with-https-self-signed-certificates-and-asp-net-core" rel="noreferrer">Create a Self-Signed Certificate and trust it on Ubuntu Linux</a></p>
  
  <p>Then I tried to find them back from the code like this:</p>
  
  <pre><code>var cert = new CertificateResolver().ResolveCertificate(CertThumbprint);
  </code></pre>
  
  <p>But it didn't work (it cannot find it).</p>
  
  <p>I also tried tried to find them using the following approach: </p>
  
  <pre><code>var store = new X509Store(StoreName.CertificateAuthority,
      StoreLocation.LocalMachine);
  
  store.Open(OpenFlags.ReadOnly);
  
  var collection = store.Certificates.Find(
      X509FindType.FindByThumbprint,
      CertThumbprint, false);
  
  store.Close();
  
  var x509Cert = collection.Count &gt; 0 ? collection[0] : null;
  </code></pre>
  
  <p>But it didn't work neither.</p>
  
  <p>So what is the right way ?</p>