我的Azure Web API从Key Vault中加载存储为密钥的证书,然后尝试从字节数组创建新的证书。在本地运行时一切正常,但是当部署到Azure时,根据传递给构造函数的KeyStorageFlags,我们会得到“拒绝访问”或“系统找不到指定的文件”错误。Web API使用.Net Core 2.2。
我已经阅读了很多相关信息,但没有涉及到这种特定情况。
使用MachineKeySet标志:
ex=拒绝访问,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) at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
以下是我们正在使用的完整代码:
在代码中,你可以看到我们尝试使用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, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags) at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
有人能证实这个适用于任何版本的 .Net 吗?可能是核心或 2.2 的 bug?
我已经阅读了很多相关信息,但没有涉及到这种特定情况。
使用MachineKeySet标志:
certificate = new X509Certificate2(pfxBytes, "",
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.Exportable);
异常:ex=拒绝访问,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) at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
使用UserKeySet标志:
certificate = new X509Certificate2(pfxBytes, "",
X509KeyStorageFlags.UserKeySet |
X509KeyStorageFlags.Exportable);
异常:
我按照这篇文章将证书作为秘密进行了加载: [https://www.rahulpnath.com/blog/pfx-certificate-in-azure-key-vault/][1] 这似乎与密钥保管库无关,因为在本地可以很好地从密钥保管库中加载秘密,并且异常并不是在Azure中抛出的。但这可能与证书的存储方式有关吗?ex=系统找不到指定的文件,stack= 在 Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags) 在 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)
以下是我们正在使用的完整代码:
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 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)
有人能证实这个适用于任何版本的 .Net 吗?可能是核心或 2.2 的 bug?