Extract Certificate from Azure KeyVault

Photo by Tim Evans / Unsplash

Azure KeyVault is a really good place for those who host their applications or kubernetes pool on Azure. It can saftly guard your Keys, Secrets and Certificates.

We are moving our payment service to kubernetes host lately. Which means we need to ditch the AppService and no local storage for certificates.

Install Nuget Packages.

First, we need to set up our environment for communicate with Azure KeyVault.
In desire project, install Azure.Security.KeyVault.Certificates and Azure.Identity nuget package.

Modify Current Method

Originally we use FilePath to retrieve our certificates. Since we are going to use Azure KeyVault as our storage, we need to modify that part and retrieve our certificate from there.
Gladly Microsoft documentation have detailed instructions.

using System;
using System.Threading.Tasks;
using Azure.Identity;
using Azure.Security.KeyVault.Certificates;

namespace Commandline
{
    class Program
    {
        static async Task Main(string[] args)
        {
            const string certificateName = "CertificateName";
            var keyVaultName = Environment.GetEnvironmentVariable("KEY_VAULT_NAME");
            var kvUri = $"https://{keyVaultName}.vault.azure.net";

            CertificateClient client = new(new Uri(kvUri), new DefaultAzureCredential());

            Console.Write($"Creating a certificate in {keyVaultName} called '{certificateName}' ...");
            CertificateOperation operation = await client.StartCreateCertificateAsync(certificateName, CertificatePolicy.Default);
            await operation.WaitForCompletionAsync();
            Console.WriteLine(" done.");

            Console.WriteLine($"Retrieving your certificate from {keyVaultName}.");
            var certificate = await client.GetCertificateAsync(certificateName);
            Console.WriteLine($"Your certificate version is '{certificate.Value.Properties.Version}'.");

            Console.Write($"Deleting your certificate from {keyVaultName} ...");
            DeleteCertificateOperation deleteOperation = await client.StartDeleteCertificateAsync(certificateName);
            // You only need to wait for completion if you want to purge or recover the certificate.
            await deleteOperation.WaitForCompletionAsync();
            Console.WriteLine(" done.");

            Console.Write($"Purging your certificate from {keyVaultName} ...");
            await client.PurgeDeletedCertificateAsync(certificateName);
            Console.WriteLine(" done.");
        }
    }
}

As you can see above we use Environment Variable to store our KeyVault name, you can also hard-coded it or store it inside your SQL Database.

Convert Certificate to X509Certificate2

In order to verify and sign our order before request is sent. It is needed that to convert certificate from KeyVaultCertificateWithPolicy to X509Certificate2.

With a magic single line of code can achieve this.

X509Certificate2 certificateWithPrivateKey = new (certificate.Value.Cer, <<CERT PASSWORD>>, X509KeyStorageFlags.MachineKeySet);

Bonus: Convert it to RSACryptoServiceProvider

If your method requires different type to work, do the convert like this:

certificateWithPrivateKey.GetRSAPublicKey() as RSACryptoServiceProvider;

Hope this simple tutorial helps!