我的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错误?
答案 0 :(得分:0)
在Azure托管的API中,添加应用程序设置:WEBSITE_LOAD_USER_PROFILE = 1解决了该问题。我们保留了EphemeralKeySet,但我怀疑UserKeySet标志也可以使用。