如何在Azure Key Vault中序列化和反序列化PFX证书?

时间:2015-11-16 03:48:52

标签: c# azure certificate x509certificate2 azure-keyvault

我有一堆字符串和pfx证书,我想存储在Azure Key保险库中,只允许用户/应用程序获取它们。将字符串存储为秘密并不难,但是如何以可以检索它的方式序列化证书并在C#中反序列化为 X509Certificate2 对象?

我试图将它存储为密钥。这是Azure powershell代码

$securepfxpwd = ConvertTo-SecureString -String 'superSecurePassword' -AsPlainText -Force
$key = Add-AzureKeyVaultKey -VaultName 'UltraVault' -Name 'MyCertificate' -KeyFilePath 'D:\Certificates\BlaBla.pfx' -KeyFilePassword $securepfxpwd

但是当我尝试使用 GetKeyAsync 方法时,我无法使用它。

5 个答案:

答案 0 :(得分:11)

这是适合您的PowerShell脚本。替换文件路径,密码,保管库名称,密码名称。

$pfxFilePath = 'C:\mycert.pfx'
$pwd = '123'
$flag = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
$collection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection 
$collection.Import($pfxFilePath, $pwd, $flag)
$pkcs12ContentType = [System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12
$clearBytes = $collection.Export($pkcs12ContentType)
$fileContentEncoded = [System.Convert]::ToBase64String($clearBytes)
$secret = ConvertTo-SecureString -String $fileContentEncoded -AsPlainText –Force
$secretContentType = 'application/x-pkcs12'
Set-AzureKeyVaultSecret -VaultName 'myVaultName' -Name 'mySecretName' -SecretValue $Secret -ContentType $secretContentType

这是一个常见问题,因此我们将对此进行改进并作为帮助者发布。

上面的脚本删除了密码,因为密码保护PFX没有价值,然后将密码存储在旁边。

答案 1 :(得分:6)

原始问题询问如何将存储的PFX检索为X509Certificate2对象。使用类似于Sumedh Barde上面发布的Base64进程(具有剥离密码的优点),以下代码将返回X509对象。在实际应用程序中,如果您要检索多个机密,则应缓存KeyVaultClient,并且还应缓存单个机密。

public static async Task<X509Certificate2> GetSecretCertificateAsync(string secretName)
{
    string baseUri = @"https://xxxxxxxx.vault.azure.net/secrets/";

    var provider = new AzureServiceTokenProvider();
    var client =  new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback));
    var secretBundle = await client.GetSecretAsync($"{baseUri}{secretName}").ConfigureAwait(false);
    string pfx = secretBundle.Value;

    var bytes = Convert.FromBase64String(pfx);
    var coll = new X509Certificate2Collection();
    coll.Import(bytes, "certificatePassword", X509KeyStorageFlags.Exportable);
    return coll[0];
}

答案 2 :(得分:1)

请参见以下答案,该答案描述了如何使用最新的.NET Azure SDK客户端库执行此操作:

How can I create an X509Certificate2 object from an Azure Key Vault KeyBundle

答案 3 :(得分:0)

以下是使用azure cli

在python中上传pfx证书的脚本
azure keyvault secret set --vault-name <Valut name> --secret-name <Secret Name> --value <Content of PFX file>

在python中获取PFX文件的内容

fh = open(self.getPfxFilePath(), 'rb')
    try:
        ba = bytearray(fh.read())
        cert_base64_str = base64.b64encode(ba)
        password = self.getPassword()
        json_blob = {
            'data': cert_base64_str,
            'dataType': 'pfx',
            'password': password
        }
        blob_data= json.dumps(json_blob)
        content_bytes= bytearray(blob_data)
        content = base64.b64encode(content_bytes)
        return content
    finally:
        fh.close
    fh.close()

答案 4 :(得分:0)

这是我解决此问题的方法。首先,将您的PFX文件转换为base64字符串。您可以使用以下两个简单的PowerShell命令来做到这一点:

$fileContentBytes = get-content 'certificate.pfx' -Encoding Byte
[System.Convert]::ToBase64String($fileContentBytes) | Out-File 'certificate_base64.txt'

通过Azure Portal在Azure Key Vault中创建机密。复制先前创建的证书base64字符串,然后通过Azure Portal将其粘贴到Azure Key Vault的秘密值字段中。然后只需从代码中调用Azure Key Vault即可获取base64字符串值并将其转换为X509Certificate2

private async Task<X509Certificate2> GetCertificateAsync()
{
    var azureServiceTokenProvider = new AzureServiceTokenProvider();
    var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
    var secret = await keyVaultClient.GetSecretAsync("https://path/to/key/vault").ConfigureAwait(false);
    var pfxBase64 = secret.Value;
    var bytes = Convert.FromBase64String(pfxBase64);
    var coll = new X509Certificate2Collection();
    coll.Import(bytes, "certificatePassword", X509KeyStorageFlags.Exportable);
    return coll[0];
}