【问题标题】:Loading X509 Certificate: Error in Azure, can't reproduce locally加载 X509 证书:Azure 中的错误,无法在本地重现
【发布时间】:2019-11-01 02:14:36
【问题描述】:

我有代码可以从我的 appsettings.json 文件中加载 X509 证书以及密码(base64 编码的 pfx 文件),如下所示:

    public static X509Certificate2 LoadSsoCertificate(IConfiguration config)
    {
        //this should be a self-signed PFX certificate with the private key included.
        var certificateText = config["SSO:x509Certificate"];
        //this should be the password to open/ read the certificate.
        var certificatePassword = config["SSO:SecretKeyPassphrase"];

        var certificateBytes = Convert.FromBase64String(certificateText);
        var cert = new X509Certificate2(certificateBytes, certificatePassword);
        return cert;
    }

这在本地测试时工作正常,但是当我部署到 Azure 应用服务时,我得到了这个神秘的异常:

Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: The specified network password is not correct
   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(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password)
   at MyCompany.AuthenticationServices.Core.Configuration.SingleSignOn.LoadSsoCertificate(IConfiguration config) in d:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\SingleSignOn.cs:line 43
   at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(Saml2Options options) in d:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\ConfigureMultiTenantSaml2Options.cs:line 51
   at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(String name, Saml2Options options) in d:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\ConfigureMultiTenantSaml2Options.cs:line 78
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Sustainsys.Saml2.AspNetCore2.Saml2Handler.<>c__DisplayClass6_0.<InitializeAsync>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 Sustainsys.Saml2.AspNetCore2.Saml2Handler.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at MyCompany.SoaToolkit.LoggingContext.AspNetCore.Middleware.Configuration.<>c.<<UseLoggingContextRequests>b__0_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

它说指定的“网络”密码不正确,但它与本地密码相同,所以我无法想象问题实际上是密码,它也不应该尝试使用“网络” .谁能在这里阐明问题所在,并提供有关如何使这个相对简单的代码工作的建议?

更新

基于 @Crypt32 的 cmets,我直接在 Azure 中创建了一个新证书并将其作为 PFX 保存到我的本地桌面,然后对其进行 Base64 编码并将其硬塞到我的 appsettings 文件中。同样,这在本地运行良好,但是当我部署到 Azure 时,我遇到了一个类似但同样令人费解的异常:

Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: The system cannot find the file specified
   at Internal.Cryptography.Pal.StorePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate2Collection.Import(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
   at MyCompany.AuthenticationServices.Core.Configuration.SingleSignOn.LoadSsoCertificate(IConfiguration config) in D:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\SingleSignOn.cs:line 40
   at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(Saml2Options options) in D:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\ConfigureMultiTenantSaml2Options.cs:line 51
   at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(String name, Saml2Options options) in D:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\ConfigureMultiTenantSaml2Options.cs:line 78
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Sustainsys.Saml2.AspNetCore2.Saml2Handler.<>c__DisplayClass6_0.<InitializeAsync>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 Sustainsys.Saml2.AspNetCore2.Saml2Handler.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at MyCompany.SoaToolkit.LoggingContext.AspNetCore.Middleware.Configuration.<>c.<<UseLoggingContextRequests>b__0_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

【问题讨论】:

  • 嗨,Jeremy,您可以尝试以下对构造函数的调用吗?新 X509Certificate2(certificateBytes, certificatePassword, X509KeyStorageFlags.MachineKeySet); X509Certificate2 构造函数可能正在尝试访问本地用户的私钥存储。即使您提供包含私钥的 pfx。
  • 我认为我无法访问 MachineKey 的东西,但我可以尝试...
  • @Anouar 我试过了,错误信息没有变化。
  • 问题要么是 PFX 文件(本地和远程 PFX 文件使用不同的密码保护),要么是构造函数调用中使用的密码。我会在服务器上调试代码并检查:PFX 是否正确,密码是否正确,并且此密码可以在本地打开 PFX。 PFX 有可能受到 Azure 不支持的算法的保护。
  • @Crypt32 pfx 和密码完全相同;我实际上部署了我在本地使用的相同 appsettings 文件,没有进行任何转换。我也看不出 Azure 如何需要来支持保护算法;不应该在 System.Security.Cryptography.X509Certificates 库中处理吗?虽然对 Internal.Cryptography.Pal.CertificatePal.FilterPFXStore() 的调用是可疑的......

标签: c# azure asp.net-core x509certificate


【解决方案1】:

好的,@Crypt32 让我走上了正确的道路,但这并不明显。

1) 问题与密码无关。这与我使用带有 Windows 10 显然支持的算法的 openssl 制作自签名证书的事实有关……但 Azure 不支持。我在 Azure 上创建了一个新证书,效果很好。

2) 我的密钥库也有问题(这是关于找不到文件的错误),原因我不明白。 Azure 似乎无法弄清楚如何为应用服务创建服务帐户密钥库,这让我大吃一惊。我切换到基于 blob 的密钥库(请参阅 here),突然之间一切似乎又开始运行了……或者至少没有启动失败。

故事的寓意:X509 错误消息比毫无价值更糟糕。它会杀死 MS 以发出实际描述问题的错误消息吗?希望这个答案能帮助其他人。

【讨论】:

  • 我遇到了同样的问题,将尝试使用 Azure 证书来查看是否可以解决问题。但是,这是否限制了 Azure 只能使用由 Azure 生成的证书?证书可以在很多地方生成....
  • 我记得这与他们支持的加密和散列算法有关。
猜你喜欢
  • 1970-01-01
  • 2019-02-02
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 2015-03-18
  • 2011-12-26
  • 1970-01-01
相关资源
最近更新 更多