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

时间:2019-03-07 19:16:55

标签: azure azure-keyvault x509certificate2 .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 =访问被拒绝,堆栈=位于   内部密码术.Pal.CertificatePal.FilterPFXStore(Byte []   rawData,SafePasswordHandle密码,PfxCertStoreFlags   pfxCertStoreFlags)在   内部密码术.Pal.CertificatePal.FromBlobOrFile(Byte []   rawData,字符串fileName,SafePasswordHandle密码,   X509KeyStorageFlags keyStorageFlags)位于   System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte []   rawData,字符串密码,X509KeyStorageFlags keyStorageFlags)

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

例外

  

ex =系统找不到指定的文件,stack =位于   内部密码术.Pal.CertificatePal.FilterPFXStore(Byte []   rawData,SafePasswordHandle密码,PfxCertStoreFlags   pfxCertStoreFlags)在   内部密码术.Pal.CertificatePal.FromBlobOrFile(Byte []   rawData,字符串fileName,SafePasswordHandle密码,   X509KeyStorageFlags keyStorageFlags)位于   System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte []   rawData,字符串密码,X509KeyStorageFlags keyStorageFlags)

我使用本文将加载证书作为秘密进行了跟踪 [https://www.rahulpnath.com/blog/pfx-certificate-in-azure-key-vault/][1]  这似乎与密钥库没有任何关系,因为它可以在本地很好地从Key Vault加载机密,并且在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;
            }
        }

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

我们如何使它起作用?

编辑:基于以下注释中的建议,尝试了EphemeralKeySet标志,但异常堆栈与其他堆栈几乎相同:

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

  

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

任何人都可以确认它可以与.Net任何版本一起使用吗?可能是核心还是2.2错误?

1 个答案:

答案 0 :(得分:0)

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