2017-08-29 2 views
5

J'essaie de configurer la protection des données et d'utiliser le certificat pour protéger les fichiers clés. Voici la documentation MS Configuring data protectionComment protéger les fichiers de clés de protection des données avec un certificat sur Asp.Net Core 2 sur debian/linux

Voici ce que je suis en train de faire:

services 
    .AddDataProtection() 
    .SetApplicationName("test server") 
    .PersistKeysToFileSystem("/home/www-data/config") 
    .ProtectKeysWithCertificate(
     new X509Certificate2("/home/www-data/config/"keyprotection.pfx); 

Lorsque je lance l'application, je reçois l'erreur suivante au démarrage:

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

Donc, la clé est créé et bien crypté. Mais il semble que d'une certaine manière, il ne sait pas comment déchiffrer comme il est dit dans l'erreur:

System.Security.Cryptography.CryptographicException: 
    Unable to retrieve the decryption key. 

Si je comprends bien, il utilise le certificat que j'ai fourni pour chiffrer la clé. Mais il semble qu'il n'utilise pas le même certificat pour le décryptage pour une raison quelconque (il semble qu'il essaie de le récupérer d'un autre endroit [store?]).

Qu'est-ce qui ne va pas?

J'ai aussi essayé de mettre le cert en magasin CA comme décrit ici: Create a Self-Signed Certificate and trust it on Ubuntu Linux

Alors j'ai essayé de les retrouver à partir du code comme ceci:

var cert = new CertificateResolver().ResolveCertificate(CertThumbprint); 

Mais cela n'a pas fonctionné (Il ne peut pas le trouver).

J'ai aussi essayé essayé de les trouver en utilisant l'approche suivante:

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; 

Mais il ne fonctionne pas non plus.

Alors, quelle est la bonne façon?

Répondre

2

Pour des raisons connues de Microsoft, les ProtectKeysWithCertificate qui acceptent les certificats overrides réels (fichiers PFX ou X509Certificate2 objets) ne sont en mesure de Crypter données DPAPI. Le déchiffrement ne fonctionne que si le même certificat est stocké dans le magasin de certificats de la machine, ce qui rend ces remplacements relativement inutiles.

Pourquoi? Qui sait. Ce n'est pas une information particulièrement utile, mais elle est vaguement rejetée here comme une "limitation du cadre sous-jacent". Dans this discussion connexe (qui était juste fermée sans aucune assistance ou engagement de Microsoft), un utilisateur partage des classes de persistance personnalisées qui ne sont pas affectées par cette "limitation" mystérieuse. GitHub repo lié ci-dessous, je sais que c'est une vieille question, mais peut-être que ça va aider quelqu'un d'autre.

https://github.com/tillig/DataProtection

Mise à jour: Ce sera corrigé dans la prochaine version de base 2.1.0: https://github.com/aspnet/Home/issues/2759#issuecomment-367157751