I am trying to configure data protection and use a certificate to protect key files. Here is the MS documentation Configuring Data Protection
Here is what I am trying to do:
services .AddDataProtection() .SetApplicationName("test server") .PersistKeysToFileSystem("/home/www-data/config") .ProtectKeysWithCertificate( new X509Certificate2("/home/www-data/config/"keyprotection.pfx);
When I launch the application, I get the following error on startup:
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 '<key id="71e2c23f-448b-49c9-984f-3c8d7227c904" version="1" />'. 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.<>c__DisplayClass1_0.<GetLazyDescriptorDelegate>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.<>c__DisplayClass1_0.<GetLazyDescriptorDelegate>b__0() at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location where exception was thrown ---
Thus, the key is created and well encrypted. But it seems that somehow he does not know how to decrypt it, since he is talking about an error:
System.Security.Cryptography.CryptographicException: Unable to retrieve the decryption key.
If I understand correctly, it uses the certificate that I provided to encrypt the key. But it seems that for some reason it is not using the same certificate for decryption (it seems he is trying to return it from another location [store?]).
What is going wrong?
I also tried putting the certificate in the CA store as described here: Create a self-signed certificate and trust it on Ubuntu Linux
Then I tried to find them from the code as follows:
var cert = new CertificateResolver().ResolveCertificate(CertThumbprint);
But this did not work (he cannot find it).
I also tried to find them using the following approach:
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 > 0 ? collection[0] : null;
But that didn't work either.
So what is the right way?