如何使用Debian / linux上的Asp.Net Core 2上的证书保护数据保护密钥文件

时间:2017-08-29 19:29:56

标签: linux asp.net-core data-protection asp.net-core-2.0

我尝试配置数据保护并使用证书来保护密钥文件。以下是MS文档Configuring data protection

以下是我要做的事情:

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

当我启动应用程序时,我在启动时收到以下错误:

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

因此密钥已创建且加密良好。但似乎它不知道如何解密它,如错误所述:

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

如果我理解正确,它会使用我提供的证书来加密密钥。但由于某些原因它似乎没有使用相同的证书进行解密(看起来它试图从其他地方[存储?]中检索它。)

出了什么问题?

我还尝试将证书放入CA存储中,如下所述: Create a Self-Signed Certificate and trust it on Ubuntu Linux

然后我试图从代码中找回它们:

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

但它没有用(它找不到它)。

我也尝试过使用以下方法找到它们:

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;

但它既没有效果。

那么正确的方法是什么?

1 个答案:

答案 0 :(得分:3)

由于只有Microsoft知道的原因,接受实际证书(PFX文件或ProtectKeysWithCertificate对象)的X509Certificate2覆盖只能加密 DPAPI数据。解密仅在机器的证书存储中存储相同的证书时才有效,这使得这些覆盖相对毫无意义。

为什么呢?谁知道。它不是特别有用的信息,但它隐约地驳回here作为基础框架的限制&#34;。

this相关讨论中(仅在没有任何Microsoft协助或参与的情况下关闭),用户共享自定义持久性类,这些类不会影响这种神秘的限制。&#34 ;下面链接的GitHub回购,我知道这是一个老问题,但也许它会帮助其他人。

https://github.com/tillig/DataProtection

更新:这将在即将推出的Core 2.1.0版本中修复: https://github.com/aspnet/Home/issues/2759#issuecomment-367157751