【问题标题】:Getting certificate from Azure KeyVault with Azure.Security.KeyVault.Secrets使用 Azure.Security.KeyVault.Secrets 从 Azure KeyVault 获取证书
【发布时间】:2021-01-23 10:46:43
【问题描述】:

我正在使用以下代码从 Azure Key Vault 获取证书

 private X509Certificate2 GetClientCertificate(string thumbprint)
        {
            var _keyVaultName = _configuration["CPC:KeyVaultUrl"];
            var connectionString = _configuration["CPC:KeyVaultCN"];
            var azureServiceTokenProvider = new AzureServiceTokenProvider(connectionString);
            var _client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
            var secretName = _configuration["CPC:ECCCertName"];
            var secret = _client.GetSecretAsync(_keyVaultName, secretName).Result;
            var privateKeyBytes = Convert.FromBase64String(secret.Value);
            var certificate = new X509Certificate2(privateKeyBytes, string.Empty, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            return certificate;
        }

它使用 Microsoft.Azure.KeyVault 库,该库已被 Azure.Security.KeyVault 取代。

如何翻译此代码以使其与新库一起使用。 (使用连接字符串与 appkey 而不是密码)

非常感谢

【问题讨论】:

    标签: azure azure-keyvault


    【解决方案1】:

    这是我用来从 Azure Key Vault 获取带有私钥的证书的代码,希望它可以帮助您解决问题:

    /// <summary>
    /// Load a certificate (with private key) from Azure Key Vault
    ///
    /// Getting a certificate with private key is a bit of a pain, but the code below solves it.
    /// 
    /// Get the private key for Key Vault certificate
    /// https://github.com/heaths/azsdk-sample-getcert
    /// 
    /// See also these GitHub issues: 
    /// https://github.com/Azure/azure-sdk-for-net/issues/12742
    /// https://github.com/Azure/azure-sdk-for-net/issues/12083
    /// </summary>
    /// <param name="config"></param>
    /// <param name="certificateName"></param>
    /// <returns></returns>
    public static X509Certificate2 LoadCertificate(IConfiguration config, string certificateName)
    {
        string vaultUrl = config["Vault:Url"] ?? "";
        string clientId = config["Vault:ClientId"] ?? "";
        string tenantId = config["Vault:TenantId"] ?? "";
        string secret = config["Vault:Secret"] ?? "";
    
        Console.WriteLine($"Loading certificate '{certificateName}' from Azure Key Vault");
    
        var credentials = new ClientSecretCredential(tenantId: tenantId, clientId: clientId, clientSecret: secret);
        var certClient = new CertificateClient(new Uri(vaultUrl), credentials);
        var secretClient = new SecretClient(new Uri(vaultUrl), credentials);
    
        var cert = GetCertificateAsync(certClient, secretClient, certificateName);
    
        Console.WriteLine("Certificate loaded");
        return cert;
    }
    
    
    /// <summary>
    /// Helper method to get a certificate
    /// 
    /// Source https://github.com/heaths/azsdk-sample-getcert/blob/master/Program.cs
    /// </summary>
    /// <param name="certificateClient"></param>
    /// <param name="secretClient"></param>
    /// <param name="certificateName"></param>
    /// <returns></returns>
    private static X509Certificate2 GetCertificateAsync(CertificateClient certificateClient,
                                                            SecretClient secretClient,
                                                            string certificateName)
    {
    
        KeyVaultCertificateWithPolicy certificate = certificateClient.GetCertificate(certificateName);
    
        // Return a certificate with only the public key if the private key is not exportable.
        if (certificate.Policy?.Exportable != true)
        {
            return new X509Certificate2(certificate.Cer);
        }
    
        // Parse the secret ID and version to retrieve the private key.
        string[] segments = certificate.SecretId.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries);
        if (segments.Length != 3)
        {
            throw new InvalidOperationException($"Number of segments is incorrect: {segments.Length}, URI: {certificate.SecretId}");
        }
    
        string secretName = segments[1];
        string secretVersion = segments[2];
    
        KeyVaultSecret secret = secretClient.GetSecret(secretName, secretVersion);
    
        // For PEM, you'll need to extract the base64-encoded message body.
        // .NET 5.0 preview introduces the System.Security.Cryptography.PemEncoding class to make this easier.
        if ("application/x-pkcs12".Equals(secret.Properties.ContentType, StringComparison.InvariantCultureIgnoreCase))
        {
            byte[] pfx = Convert.FromBase64String(secret.Value);
            return new X509Certificate2(pfx);
        }
    
        throw new NotSupportedException($"Only PKCS#12 is supported. Found Content-Type: {secret.Properties.ContentType}");
    }
    

    }

    【讨论】:

    • 找不到 CertificateClient
    • @Pangamma CertificateClient 可以在 Azure.Security.KeyVault.Certificates nuget 包中找到
    • PemEncoding 这种更简单的方法有什么例子吗?我想不通。
    • 我想我只是将我的证书作为 .pfx 文件上传到 AKV,然后使用上面的代码下载它。我知道 ,NET 5 中的 .pem 支持更好,但从未尝试过。
    猜你喜欢
    • 2018-12-17
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 2019-11-08
    相关资源
    最近更新 更多