.NET Core 2.2,Azure Web API 新 X509Certificate2“系统找不到指定的文件”和“访问被拒绝”

use*_*078 5 azure x509certificate2 azure-keyvault .net-core-2.2

我的 Azure Web API 加载在 Key Vault 中存储为机密的证书,然后尝试从字节数组创建新证书。在本地运行一切正常,但是,当部署到 Azure 时,我们会收到拒绝访问系统找不到根据传递给构造函数的 KeyStorageFlags指定的文件。Web API 使用 .Net Core 2.2

我已经在这方面阅读了大量与此相关的信息,但不是这个特定场景。

使用 MachineKeySet 标志: certificate = new X509Certificate2(pfxBytes, "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);

例外

ex=Access denied, stack= 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) 在 System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)

使用 UserKeySet 标志: certificate = new X509Certificate2(pfxBytes, "", X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.Exportable);

例外

ex=系统找不到指定的文件,stack= at Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags) at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData,字符串文件名,SafePasswordHandle 密码,X509KeyStorageFlags keyStorageFlags) 在 System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)

我使用这篇文章将加载证书作为秘密 [ https://www.rahulpnath.com/blog/pfx-certificate-in-azure-key-vault/][1] 这似乎没有任何关系使用密钥保管库,因为它可以在本地很好地从密钥保管库加载机密,并且在 Azure 中加载不是引发异常的地方。但这可能与证书的存储方式有关?

这是我们正在使用的完整代码

private async Task<X509Certificate2> GetSecretCertificateFromKVAPI()
        {
            try
            {
                var keyVaultName = _configuration["Secrets:KeyVaultName"];

                var keyVaultEndpoint = $"https://{keyVaultName}.vault.azure.net:443/secrets/";
                var provider = new AzureServiceTokenProvider();
                var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback));
                SecretBundle secretRetrieved;

                secretRetrieved = await client.GetSecretAsync($"{keyVaultEndpoint}OdysseyCA");

                var pfxBytes = Convert.FromBase64String(secretRetrieved?.Value);

                //note, must pass an empty password when loading from keyvault in Azure
                X509Certificate2 certificate;
                try
                {
                    // or recreate the certificate directly
                    certificate = new X509Certificate2(pfxBytes, "",
                            X509KeyStorageFlags.MachineKeySet |
                            X509KeyStorageFlags.PersistKeySet |
                            X509KeyStorageFlags.Exportable);

                    // alternative, try using import
                    //var coll = new X509Certificate2Collection();
                    //coll.Import(pfxBytes, null, X509KeyStorageFlags.Exportable);
                    //certificate = coll[0];
                }
                catch (Exception ex)
                {
                    _logger.Trace($"create new X509 failed, ex={ex.Message}, stack={ex.StackTrace}");
                    throw;
                }

                return certificate;
            }
            catch (Exception ex)
            {
                _logger.Trace($"GetSecretCertificateFromKVAPI threw an exception, ex={ex.Message}, stack = {ex.StackTrace}");
                throw;
            }
        }
Run Code Online (Sandbox Code Playgroud)

在代码中,您可以看到我们尝试使用 X509Certificate2Collection 类的 .import 方法来解决此问题,但结果是相同的。我们正在积极备份到 .Net Core 2.1 和 2.0 以查看这是否是一个新错误并寻找其他答案。

我们如何让它发挥作用?

编辑:根据下面评论中的建议尝试使用 EphemeralKeySet 标志,但异常堆栈与其他异常堆栈几乎相同:

certificate = new X509Certificate2(pfxBytes, "", X509KeyStorageFlags.EphemeralKeySet | X509KeyStorageFlags.Exportable);

ex=系统找不到指定的文件,stack = at Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags) at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData,字符串文件名,SafePasswordHandle 密码,X509KeyStorageFlags keyStorageFlags) 在 System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)

任何人都可以确认这适用于 .Net 任何版本吗?可能的核心或 2.2 错误?

use*_*078 12

在 Azure 托管的 API 中,添加应用程序设置:WEBSITE_LOAD_USER_PROFILE=1 解决了问题。我们继续使用 EphemeralKeySet,但我怀疑 UserKeySet 标志也可以使用。