gpt4 book ai didi

c# - .NET Core X509Certificate2 使用(Windows/IIS、Docker、Linux下)

转载 作者:太空狗 更新时间:2023-10-29 21:37:29 25 4
gpt4 key购买 nike

我真的很长时间都在尝试在 .NET Core API 中使用证书。

基本上,我需要在 IIS 和 docker 上运行的 .NET Core web api 中使用它们。

我需要使用的证书用于:

Microsoft.AspNetCore.DataProtection

public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(dataProtectionKeystorePath))
.ProtectKeysWithCertificate
(
new X509Certificate2(dataProtectionCertificatePath, dataProtectionCertificateSecret)
);
}

Kestrel Options to set SSL certificate
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel
(
options =>
{
options.Listen(address, port, listenOptions =>
{
listenOptions.UseHttps(new X509Certificate2(sslCertificatePath, sslCertifciateSecret));
}
);
}
)
// other setup
;

IdentityServer4.SigningCredentials

注意:此代码适用于从 VS2017 开始的开发机​​器,但会在 Windows 2008 R2 IIS 测试服务器上引发这些异常。
services.AddIdentityServer()
.AddSigningCredential
(
new X509Certificate2(tokenCertificatePath, tokenCertificatePassphrase)
)
// other setup
;

这三个都意味着放置一个证书文件,使用构造函数加载它,传递 secret ,然后我们开始吧。

sarkasm > 祝我快乐,这很容易。 < 萨卡斯姆

所以我创建了一个 certs subdir 来保存证书。添加了 secret 的设置。验证所有值都按预期加载/创建。已验证文件位于预期位置并因此存在。简而言之,例如:
string dataProtectionKeystorePath = System.Path.Combine(Environment.ContentRootPath, "keystore");
string dataProtectionCertificatePath = System.Path.Combine(Environment.ContentRootPath, "certs", "keystore.pfx");
string dataProtectionSecret = Configuration.GetSection("CertificateSecrets").GetValue<string>("keystoreSecret", null);

string tokenCertificatePath = System.Path.Combine(Environment.ContentRootPath, "certs", "token.pfx");
string tokenCertificateSecret = Configuration.GetSection("CertificateSecrets").GetValue<string>("tokenSecret", null);

string sslCertificatePath = System.Path.Combine(Environment.ContentRootPath, "certs", "ssl.pfx");
string sslCertificateSecret = Configuration.GetSection("CertificateSecrets").GetValue<string>("tokenSecret", null);

他们说,让我们玩得开心。所以让我们去部署吧。

我最终得到的是这些异常(exception):

数据保护异常(exception):
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58]
Creating key {39560783-e349-475e-8e3f-748abb8c6c8b} with creation date 2018-11-16 08:01:49Z, activation date 2018-11-16 08:01:49Z, and expiration date 2019-02-14 08:01:49Z.
info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39]
Writing data to file '[intentionally removed for post]'.
fail: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[24]
An exception occurred while processing the key element '<key id="39560783-e349-475e-8e3f-748abb8c6c8b" version="1" />'.
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset does not exist
at Internal.NativeCrypto.CapiHelper.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeProvHandle()
at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeKeyHandle()
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 keySize, CspParameters parameters, Boolean useDefaultKeySize)
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)
at Internal.Cryptography.Pal.CertificatePal.<>c.<GetRSAPrivateKey>b__61_0(CspParameters csp)
at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)
at Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()
at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate)
at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.EncryptedXmlWithCertificateKeys.GetKeyFromCert(EncryptedKey encryptedKey, KeyInfoX509Data keyInfo)
at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.EncryptedXmlWithCertificateKeys.DecryptEncryptedKey(EncryptedKey encryptedKey)
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 {39560783-e349-475e-8e3f-748abb8c6c8b} is ineligible to be the default key because its CreateEncryptor method failed.
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset does not exist
at Internal.NativeCrypto.CapiHelper.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeProvHandle()
at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeKeyHandle()
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 keySize, CspParameters parameters, Boolean useDefaultKeySize)
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)
at Internal.Cryptography.Pal.CertificatePal.<>c.<GetRSAPrivateKey>b__61_0(CspParameters csp)
at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)
at Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()
at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate)
at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.EncryptedXmlWithCertificateKeys.GetKeyFromCert(EncryptedKey encryptedKey, KeyInfoX509Data keyInfo)
at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.EncryptedXmlWithCertificateKeys.DecryptEncryptedKey(EncryptedKey encryptedKey)
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 {39560783-e349-475e-8e3f-748abb8c6c8b} is ineligible to be the default key because its CreateEncryptor method failed.
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Keyset does not exist
at Internal.NativeCrypto.CapiHelper.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeProvHandle()
at System.Security.Cryptography.RSACryptoServiceProvider.get_SafeKeyHandle()
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 keySize, CspParameters parameters, Boolean useDefaultKeySize)
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)
at Internal.Cryptography.Pal.CertificatePal.<>c.<GetRSAPrivateKey>b__61_0(CspParameters csp)
at Internal.Cryptography.Pal.CertificatePal.GetPrivateKey[T](Func`2 createCsp, Func`2 createCng)
at Internal.Cryptography.Pal.CertificatePal.GetRSAPrivateKey()
at Internal.Cryptography.Pal.CertificateExtensionsCommon.GetPrivateKey[T](X509Certificate2 certificate, Predicate`1 matchesConstraints)
at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate)
at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.EncryptedXmlWithCertificateKeys.GetKeyFromCert(EncryptedKey encryptedKey, KeyInfoX509Data keyInfo)
at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.EncryptedXmlWithCertificateKeys.DecryptEncryptedKey(EncryptedKey encryptedKey)
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 ---
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)

Identity Server 4 签名凭证的异常(exception)情况
Application startup exception: Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: An internal error occurred
at Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
at AuthServer.Startup.ConfigureServices(IServiceCollection services) in [intentionally removed for post]\Startup.cs:line 136
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.Initialize()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
crit: Microsoft.AspNetCore.Hosting.Internal.WebHost[6]
Application startup exception
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: An internal error occurred
at Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
at AuthServer.Startup.ConfigureServices(IServiceCollection services) in [intentionally removed for post]\Startup.cs:line 136
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.Initialize()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

SSL证书的异常(exception)
Unhandled Exception: Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: An internal error occurred
at Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
at AuthServer.Program.<>c.<BuildWebHost>b__1_3(ListenOptions listenOptions) in [intentionally removed for post]\Program.cs:line 58
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions.Listen(IPEndPoint endPoint, Action`1 configure)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions.Listen(IPAddress address, Int32 port, Action`1 configure)
at Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String name, TOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.CreateServiceContext(IOptions`1 options, ILoggerFactory loggerFactory)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer..ctor(IOptions`1 options, ITransportFactory transportFactory, ILoggerFactory loggerFactory)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureServer()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
at MyProject.Program.Main(String[] args) in [intentionally removed for post]\Program.cs:line 47

几个月来一直面对这个证书异常,谷歌搜索并再次面对这个异常,无论我尝试过什么(根据谷歌结果,在 github 上提出的问题等等),我想到我错过了一些重要的东西。

我尝试使用 StorageFlags,但没有找到一个(组合)工作。

这些项目应该在 Windows (IIS)、docker 和曾经的 linux (ubuntu, debian) 上运行。这就是为什么我们决定将证书放在(跨多个实例安装)子目录中。所以我发现的建议将证书安装到微软证书存储中的帖子将不起作用。怎么能在 docker 和 linux 上呢?

由于我倾向于使用的所有证书都受到影响,因此问题可能是我对如何使用证书有重大误解。

谁能帮我找出我错过的主要观点并最终获得证书运行?我需要配置一些东西吗?如果是什么?

只是一些调查总结:

我确定这些文件存在吗:是的,否则异常(exception)将是
System.Security.Cryptography.CryptographicException: System cannot find specified file.

我确定密码正确吗:是的,否则异常(exception)是
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: The specified network password is not correct.

文件权限:感谢 CheshireCat 提醒我。在 Windows Server 2008 R2 IIS 7.5 上,我检查了用户 DefaultAppPool 的 certs 子目录的文件权限(认为现在是不同的用户单元)。对 certs 子目录的完全访问文件权限已授予用户 DefaultAppPool like shown in this link .

通常 IS4 签名凭据异常发生在应用程序启动时。使用 X509KeyStorageFlags.MachineKeySet 不会在启动时抛出,但会显示登录窗口并在登录后抛出。不会返回任何 token ,但会创建一个 session ,以便用户可以修改 ASP NET 标识帐户设置。

证书过期:证书可以过期。数据保护似乎不会检查过期日期,因此即使证书过期也可以使用。 Identity Server 4 签名凭据仍然可以使用,但如果证书过期,ASP.NET 核心 token 验证将引发未经授权。

问题解决

一年半后,解决方案是:以某种方式损坏(自签名/自创建)证书。

可以使用以下代码检查证书是否有效:
  static void Main(string[] args)
{
X509Certificate2 cert = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "cert.pfx"), "password");
Console.WriteLine("cert private key: " + cert.PrivateKey);
}

如果您看到以下输出,则证明证书良好,否则您会收到上述异常。
cert private key: System.Security.Cryptography.RSACng

创建用于开发的证书

SSL证书

使用 dotnet 工具 dev-certs。此调用会打开一个提示,然后将 localhost SSL 证书导入 CurrentUser 证书存储 ( view it with MMC )。无需更改程序中的代码。
dotnet dev-certs https --trust

其他证书

创建了“损坏的”证书 using makecert .我切换到 OpenSSL但也可以是 New-SelfSignedCertificate使用的工具(如果您使用的是 Win 10)。

如果 OpenSSL 安装正确并添加到 PATH 变量,以下批处理文件将创建工作证书(需要用户交互!)。
  openssl genrsa 2048 > private.pem
openssl req -x509 -days 365 -new -key private.pem -out public.pem
openssl pkcs12 -export -in public.pem -inkey private.pem -out cert.pfx
REM openssl pkcs12 -info -in cert.pfx
certutil -dump cert.pfx
PAUSE

本地开发设置(Win 7、VS 2017、IIS Express/Kestrel)

正如 Cheshire-Cat(再次非常感谢您)描述的所有部分的代码都按预期在 .NET Core 2.1 下工作。包括数据保护和 Identity Server 4 签名凭据。

在 Windows 2008 R2 上部署到 IIS 7.5

乐趣还在继续。让证书在本地开发机器上工作并将其部署到 IIS 会引发"new"异常。
  • 检查 IIS 上的文件权限(DefaultAppPool 具有完全权限)
  • 证书与在本地机器上工作的证书相同
  • 没有安装使用的证书(不在开发机器上,不在 IIS 机器上),所以应该采用实际的文件。

  • 日志显示基本良好的设置
      using data protection keystore path C:\inetpub\wwwroot\auth\keystore
    data protection keystore is protected with certificate at path 'C:\inetpub\wwwroot\auth\certs\keystore.pfx'
    loading keystore certificate from file 'C:\inetpub\wwwroot\auth\certs\keystore.pfx'
    loading keystore certificate with passphrase ********

    Application startup exception: Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: An internal error occurred
    at Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
    at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
    at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
    at [SomeOfMyNamespaces].X509Certificate2Loader.LoadFromFile(String certName, String certPath, String certPassphrase, ILogger logger) in [intentionally-blanked]\X509Certificate2Loader.cs:line 57
    at [SomeOfMyNamespaces].DataProtectionExtensions.AddDataProtection(IServiceCollection services, IConfiguration config, IHostingEnvironment environment, String applicationName, String applicationVersion, ILogger logger) in [intentionally-blanked]\DataProtectionExtensions.cs:line 207
    at [SomeOfMyNamespaces].Startup.ConfigureServices(IServiceCollection services) in [intentionally-blanked]\Startup.cs:line 96
    --- End of stack trace from previous location where exception was thrown ---
    at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
    at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
    at Microsoft.AspNetCore.Hosting.Internal.WebHost.Initialize()
    --- End of stack trace from previous location where exception was thrown ---
    at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
    crit: Microsoft.AspNetCore.Hosting.Internal.WebHost[6]
    Application startup exception
    Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: An internal error occurred
    at Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
    at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
    at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
    at [SomeOfMyNamespaces].X509Certificate2Loader.LoadFromFile(String certName, String certPath, String certPassphrase, ILogger logger) in [intentionally-blanked]\X509Certificate2Loader.cs:line 57
    at [SomeOfMyNamespaces].DataProtectionExtensions.AddDataProtection(IServiceCollection services, IConfiguration config, IHostingEnvironment environment, String applicationName, String applicationVersion, ILogger logger) in [intentionally-blanked]\DataProtectionExtensions.cs:line 207
    at [SomeOfMyNamespaces].Startup.ConfigureServices(IServiceCollection services) in [intentionally-blanked]\Startup.cs:line 96
    --- End of stack trace from previous location where exception was thrown ---
    at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
    at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
    at Microsoft.AspNetCore.Hosting.Internal.WebHost.Initialize()
    --- End of stack trace from previous location where exception was thrown ---
    at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

    引用的第 57 行是:
      cert = new X509Certificate2(certPath, certPassphrase);

    Identity Server 4 签名凭据也会出现相同的异常。

    给予另一个 100 的奖励以帮助我在 Windows Server 2008 R2 上的 IIS 上运行它。

    IIS 和 docker(以及本地开发)的解决方案:使用这个并且 IIS 和 Docker 设置都不会提示:
    cert = new X509Certificate2(certPath, certPassphrase, X509KeyStorageFlags.MachineKeySet);

    最佳答案

    我在 IS4 项目上运行的实际代码是这样的:

    X509Certificate2 certificate = null;

    // Load certificate from Certificate Store using the configured Thumbprint
    using (X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
    {
    store.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindByThumbprint, appConfiguration.CertificateThumbprint, false);

    if (certificates.Count > 0)
    certificate = certificates[0];
    }

    // Fallback to load certificate from local file
    if (certificate == null)
    {
    string path = Path.Combine("C:\\Certificates", appConfiguration.CertificateFilename);

    try
    {
    certificate = new X509Certificate2(path, "CertificateSecret123$");
    logger.LogInformation($"Found from file {certificate.Thumbprint}");
    }
    catch (Exception ex)
    {
    logger.LogError(ex, $"Certificate file error {path}");
    certificate = null;
    }
    }

    if (certificate == null)
    throw new Exception($"Certificate {appConfiguration.CertificateThumbprint} not found.");

    builder.AddSigningCredential(certificate);

    如果我更改指纹以强制代码从本地文件中查找证书,则会得到预期的结果:

    Result

    更新 2018/11/19

    我更正了代码中的一个错误,因为如果找不到证书文件, X509Certificate2类构造函数抛出异常。所以,其实之前的 if (certificate == null)控制后线 certificate = new X509Certificate2... ,永远不会达到。

    使代码工作的步骤是:
  • 创建证书并将其放入目录
  • 检查运行代码的用户对文件夹的目录权限。
  • 如果您在 开发机 , 检查运行 VS 的用户是否有访问文件所在目录的权限。
  • 如果您在 IIS ,查看 AppPool托管您的应用程序及其执行的用户。它需要对证书目录具有权限。
  • 加载证书来自文件 使用示例代码。确保路径的正确性。
  • 加载证书来自商店 使用指纹。要获取证书指纹,您可以:
  • 使用 PowerShell 命令 Get-ChildItem -path cert:\LocalMachine\My指定您在商店中注册证书的正确位置。
  • 通过右键单击 .pfx 文件使用 Windows 资源管理器 -> 打开 -> 在 MMC 控制台中找到您的文件 -> 双击它 -> 详细信息 -> 指纹。 重要提示 :当从预览文本框中复制/粘贴 Thumbprint 值时,Windows 中有一个众所周知的丑陋错误。 在指纹开头添加隐藏字符 粘贴值时。因此,首先将其复制/粘贴到文本编辑器上,然后通过在第一个字符附近移动箭头键来检查它。另见 this .
  • 关于c# - .NET Core X509Certificate2 使用(Windows/IIS、Docker、Linux下),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53334142/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com