通过 IKeyVaultClient.GetCertificateAsync 检索时,Azure Key Vault 证书没有私钥
Azure Key Vault Certificates does not have the Private Key when retrieved via IKeyVaultClient.GetCertificateAsync
我有 2 种方法来做同样的事情,但 Azure 已弃用一种有效的方法,另一种方法无效。
有效但已弃用的方法:
我将我的 PFX 存储在 Azure Key Vault Secrets 中。 (当我创建秘密时,我看到一条警告,指出此功能已弃用)
并使用以下代码检索它以创建我的证书:
SecretBundle secret = await keyVaultClient.GetSecretAsync(keyVaultUrl, "MyCert-Secret");
X509Certificate2Collection exportedCertCollection = new X509Certificate2Collection();
exportedCertCollection.Import(Convert.FromBase64String(secret.Value));
X509Certificate2 certFromSecret = exportedCertCollection.Cast<X509Certificate2>().Single(s => s.HasPrivateKey);
感谢
我能够使用此证书成功托管和访问我的应用程序。
这种方法行不通,但我应该使用:
我将我的证书存储在 Azure 密钥保管库中 证书
并使用以下代码检索它并创建 X509Certificate2:
CertificateBundle certificateBundle = await keyVaultClient.GetCertificateAsync(keyVaultUrl, "MyCert-Certificate");
X509Certificate2 certFromCertificate = new X509Certificate2(certificateBundle.Cer);
这种方法的问题是证书不包含私钥。即 certFromCertificate.HasPrivateKey 是错误的。
我的问题
为什么 certFromSecret 有私钥,而 certFromCertificate 没有?
如何从密钥保管库中检索证书,我可以在密钥保管库中创建 X509Certificate2 对象以使用 UseHttps 在 Kestrel 中托管我的应用程序。
@Adrian 的第 2 部分 很好地解释了 Azure KV 证书的概念,我已经更改了我的代码如下以获得包括私钥的完整证书:
SecretBundle secret = await kv.GetSecretAsync(keyVaultUrl, certName);
X509Certificate2 certificate =
new X509Certificate2(Convert.FromBase64String(secret.Value));
诀窍是使用 GetSecretAsync
而不是 GetCertificateAsync
。请参考 Adrian 的 以了解为什么必须使用秘密来获取带有私钥的完整证书。
请注意,您应该使用 Azure 证书的 属性 页面中的 "Certificate identifier" 属性(url 和“/secrets/”)。
最新版本的SDK(Azure.Security.KeyVault.Certificates 4.2.0)现在有DownloadCertificateAsync方法,可以直接获取完整的证书(即私钥)。
文档指出:
Because Cer contains only the public key, this method attempts to
download the managed secret that contains the full certificate.
X509Certificate2 cert = await certificateClient.DownloadCertificateAsync(certName);
我有 2 种方法来做同样的事情,但 Azure 已弃用一种有效的方法,另一种方法无效。
有效但已弃用的方法:
我将我的 PFX 存储在 Azure Key Vault Secrets 中。 (当我创建秘密时,我看到一条警告,指出此功能已弃用)
并使用以下代码检索它以创建我的证书:
SecretBundle secret = await keyVaultClient.GetSecretAsync(keyVaultUrl, "MyCert-Secret");
X509Certificate2Collection exportedCertCollection = new X509Certificate2Collection();
exportedCertCollection.Import(Convert.FromBase64String(secret.Value));
X509Certificate2 certFromSecret = exportedCertCollection.Cast<X509Certificate2>().Single(s => s.HasPrivateKey);
感谢
我能够使用此证书成功托管和访问我的应用程序。
这种方法行不通,但我应该使用:
我将我的证书存储在 Azure 密钥保管库中 证书
并使用以下代码检索它并创建 X509Certificate2:
CertificateBundle certificateBundle = await keyVaultClient.GetCertificateAsync(keyVaultUrl, "MyCert-Certificate");
X509Certificate2 certFromCertificate = new X509Certificate2(certificateBundle.Cer);
这种方法的问题是证书不包含私钥。即 certFromCertificate.HasPrivateKey 是错误的。
我的问题
为什么 certFromSecret 有私钥,而 certFromCertificate 没有?
如何从密钥保管库中检索证书,我可以在密钥保管库中创建 X509Certificate2 对象以使用 UseHttps 在 Kestrel 中托管我的应用程序。
@Adrian 的第 2 部分
SecretBundle secret = await kv.GetSecretAsync(keyVaultUrl, certName);
X509Certificate2 certificate =
new X509Certificate2(Convert.FromBase64String(secret.Value));
诀窍是使用 GetSecretAsync
而不是 GetCertificateAsync
。请参考 Adrian 的
请注意,您应该使用 Azure 证书的 属性 页面中的 "Certificate identifier" 属性(url 和“/secrets/”)。
最新版本的SDK(Azure.Security.KeyVault.Certificates 4.2.0)现在有DownloadCertificateAsync方法,可以直接获取完整的证书(即私钥)。
文档指出:
Because Cer contains only the public key, this method attempts to download the managed secret that contains the full certificate.
X509Certificate2 cert = await certificateClient.DownloadCertificateAsync(certName);