加载 X509 证书:Azure 中出错,无法在本地重现

Loading X509 Certificate: Error in Azure, can't reproduce locally

我有代码可以从我的 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\s\MyCompany.AuthenticationServices.Core\Configuration\SingleSignOn.cs:line 43
   at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(Saml2Options options) in d:\a\s\MyCompany.AuthenticationServices.Core\Configuration\ConfigureMultiTenantSaml2Options.cs:line 51
   at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(String name, Saml2Options options) in d:\a\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)

它说指定的 "network" 密码不正确,但它是本地有效的相同密码,所以我无法想象问题实际上是密码,而且它不应该尝试使用"network" 要么。任何人都可以在这里阐明问题所在,并就如何使这个相对简单的代码工作提供建议吗?

更新

根据@Crypt32 的评论,我直接在 Azure 中创建了一个新证书并将其作为 PFX 保存到我的本地桌面,然后对其进行 Base64 编码并将其硬塞到我的应用程序设置文件中。同样,这在本地运行良好,但当我部署到 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\s\MyCompany.AuthenticationServices.Core\Configuration\SingleSignOn.cs:line 40
   at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(Saml2Options options) in D:\a\s\MyCompany.AuthenticationServices.Core\Configuration\ConfigureMultiTenantSaml2Options.cs:line 51
   at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(String name, Saml2Options options) in D:\a\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 让我走上了正确的道路,但并不明显。

1) 问题与密码无关。这与我使用 openssl 和 Windows 10 显然支持的算法制作自签名证书的事实有关......但 Azure 不支持。我在 Azure 上创建了一个新证书并且运行良好。

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

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