15

我正在使用 Azure Key Vault 来保护我们的密钥和机密,但我不确定如何使用通过 .net SDK 检索的 KeyBundle。如何创建 X509Certificate2 对象?

4

4 回答 4

26

在 KeyVault 中导入/创建证书时,会创建 3 个实体:

  • 证书 - 包含有关证书的所有相关详细信息,包括其公共部分(即公钥、有效期、指纹等)

  • Secret - 包含 base64 中的私钥(证书的私有部分)

  • 关键 - 我不知道,但与此线程无关。

您可以X509Certificate2使用 Certificate 对象或 Secret 对象创建对象。

如果您希望X509Certificate2包含私钥,那么您当然需要获取 Secret 实体的值并执行以下操作:

SecretBundle certificatePrivateKeySecretBundle =
    await keyVaultClient.GetSecretAsync(certificateIdentifierSecretPart);

byte[] privateKeyBytes = Convert.FromBase64String(certificatePrivateKeySecretBundle.Value);
X509Certificate2 certificateWithPrivateKey = new X509Certificate2(privateKeyBytes, (string) null, X509KeyStorageFlags.MachineKeySet);

certificateIdentifierSecretPart等于证书的秘密部分路径 :https://<vault name>.vaults.azure.net/secrets/<certificate name>

注意/secrets/路径。

于 2018-05-20T16:59:44.973 回答
11

2020 年 11 月更新:

在当前版本的 Azure Key Vault 中,证书 是一流的概念,而不是一种机密。

如果您的 Key Vault 实例已经有一个带有可导出私钥的证书,您将获取它并按X509Certificate2如下方式进行水合:

使用DefaultAzureCredential创建所需的客户端

var certClient = new CertificateClient(new Uri("https://yourKeyVault.vault.azure.net/"), new DefaultAzureCredential());
var secretClient = new SecretClient(new Uri("https://yourKeyVault.vault.azure.net/"), new DefaultAzureCredential());

获取证书,其中包含指向私钥的链接。

注意:Key Vault Secrets 库的最新(4.2.0 测试版)版本包括一个名为KeyVaultSecretIdentifier的帮助程序类,它会为您执行此解析。

Response<KeyVaultCertificateWithPolicy> certResponse = await certClient.GetCertificateAsync("testCert");

// If using client version 4.2.0 or later
KeyVaultSecretIdentifier identifier = new KeyVaultSecretIdentifier(certResponse.Value.SecretId);

// Else, Get the secretId and parse out the parts needed to fetch the secret.
Uri secretId = certResponse.Value.SecretId;
var segments = secretId.Segments;
string secretName = segments[2].Trim('/');
string version = segments[3].TrimEnd('/');

获取证书的秘密并使用它来构造一个新的X509Certificate2.

// If using client version 4.2.0 or later
Response<KeyVaultSecret> secretResponse = await secretClient.GetSecretAsync(identifier.Name, identifier.Version);

// else
Response<KeyVaultSecret> secretResponse = await secretClient.GetSecretAsync(secretName, version);

KeyVaultSecret secret = secretResponse.Value;
byte[] privateKeyBytes = Convert.FromBase64String(secret.Value);

var cert = new X509Certificate2(privateKeyBytes);

有关最新的 Key Vault 证书和机密客户端的更多信息,请在此处查看其各自的 README 文档:

Azure.Security.KeyVault.Certificates旧版本的迁移指南

Azure.Security.KeyVault.Secrets旧版本的迁移指南

于 2020-11-10T23:08:00.607 回答
1

您不能将 KeyBundle 结果用作 X509Certificate2 对象,因为它在这里仅表示密钥对的公钥部分(无颁发者)。有关使用此 KeyBundle 对象加密数据、验证签名等的功能,请参阅KeyVaultClientExtensions中的方法。

于 2016-05-05T01:16:27.610 回答
1

使用新的 Azure.Security.KeyVault.* 库并在Christopher Scott回答的基础上进行构建时,您可以加载所有活动的和未过期的版本,并使用以下内容跳过 GetCertificate 和解析步骤:

public static IEnumerable<X509Certificate2> LoadCertificateVerisons(
    string keyVaultName,
    string certificateName)
{
    var keyVaultUrl = new Uri($"https://{keyVaultName}.vault.azure.net");
    var certificateClient = new CertificateClient(keyVaultUrl, new AzureCliCredential());
    var secretClient = new SecretClient(keyVaultUrl, new AzureCliCredential());

    var versions = certificateClient.GetPropertiesOfCertificateVersions(certificateName).ToArray();

    foreach (var certificate in versions)
    {
        if (!certificate.Enabled.GetValueOrDefault(false) ||
            certificate.ExpiresOn <= DateTimeOffset.UtcNow) continue;

        var certificateSecret = secretClient.GetSecret(certificate.Name, certificate.Version).Value;
        var privateKey = Convert.FromBase64String(certificateSecret.Value);
        yield return new X509Certificate2(privateKey, (string) null, X509KeyStorageFlags.MachineKeySet);
    }
}
于 2021-04-14T09:52:38.650 回答