Azure Key Vault- Safeguard Signing/Encryption Keys, Secrets and Certificates

Secret vault is where you hide your secrets like digital signing keys, encryption/decryption keys, api keys, client certificates and other general purpose secrets. There are number of on-premise secret vault solutions but they are expensive to buy and to maintain. Good news is, you can get ready go solutions in the cloud and you have multiple options to choose from- Azure Key Vault, AWS KMS, AWS Cloud HSM, etc. Today, we are going to talk about Azure Key Vault which is a cloud based service in Microsoft Azure and you can use Key Vault to store keys, secrets and certificates.

Azure Key Vault is multi-tenant service and it supports two flavor of keys- soft and hard. Hard key is HSM (Hardware Security Module) protected and validated to FIPS 140-2 Level 2. Soft key is software-protected and processed inside cryptographic modules validated to FIPS 140-2 Level 1. TSA or some other organizations recommend HSM protected key and validated to FIPS 140-2 Level 3. Level 3 requires HSM cluster be single tenant. So, Azure Key Vault is NOT going to work for you if you have to comply with FIPS 140-2 Level 3. You can use AWS Cloud HSM and it is FIPS 140-2 Level 3 compliant. For now, let’s focus on Azure Key Vault and be happy with FIPS 140-2 Level 2 validation which is sufficient for most of the use cases!

Another important requirement is cryptographic algorithm supported by Azure Key Vault. Key Vault supports RSA and Elliptic Curve keys only. Key Vault supports RSA keys of sizes 2048, 3072 and 4096. Key Vault supports Elliptic Curve key types P-256, P-384, P-521, and P-256K (SECP256K1). Follow this link for more info. For the purpose of this demo, we are using premium service tier which comes with HSM. You would not see HSM key options if you are using basic tier.

Azure Key Vault is offered in two service tiers—standard and premium. HSM is available in premium service tier only. Software keys are almost free. HSM key pricing is based on the key strength. You can find the pricing here.

Key Vault is critical security infrastructure and you must think of governance and secure access to your key vaults by allowing only authorized applications and users. It’s very important that you read security best practice- Secure access to a key vault. Let me share access model overview in case you don’t have time to read the entire document!

You will need to create a service principal, create an access policy and grant the service principal permission. Client applications use this service principal to authenticate against Azure AD and interact with key vault given the access policy. For better security, we would use client certificate with service principal for authentication against Azure AD.

Service Principal configured with public keys (.cer file). Don’t upload your pfx file here! Pfx file should be stored locally at the secure location.

Here is a sample access policy (follow the least privilege principle)-

Firewall and virtual network

Concept of multiple layers of security (defense in depth) control should be utilized. Key Vault must be configured to allow access from virtual network for added security. You can add selective and trusted external IP addresses to the firewall to allow access.

Okay, we have covered the basics and, now, let’s jump on to the code to see Key Vault in action! Sample code for the Azure Key Vault to demonstrate digital signature, encrypt/decrypt, key wrapping, secret management, encrypted secret management and more. You can get complete source code at GitHub but here are couple of snippets-

Program.cs:

using Microsoft.Extensions.Configuration;
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace ASPNET4YOU.AzureKeyVault
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var builder = new ConfigurationBuilder()
                                .SetBasePath(Directory.GetCurrentDirectory())
                                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

                IConfigurationRoot configuration = builder.Build();

                string clientId = configuration.GetSection("clientId").Value;
                string customerMasterKeyId = configuration.GetSection("customerMasterKeyId").Value;
                string vaultAddress = configuration.GetSection("vaultAddress").Value;
                string myCertFile = configuration.GetSection("myCertFile").Value;

                // In real-world application, you must set a password to the cert! This cert was created
                // in Azure Key Vault, exported with the private key and deleted from there. Export does not
                // require password!! Okay to use this cert for authentication to Key Vault for this tests!
                X509Certificate2 myCert = new X509Certificate2(myCertFile, "", X509KeyStorageFlags.PersistKeySet);

                SampleKeyVault vault = new SampleKeyVault(customerMasterKeyId, clientId, vaultAddress, myCert);

                SampleDigitalSignature digitalSignature = new SampleDigitalSignature(vault);
                digitalSignature.TestDigitalSignature().GetAwaiter().GetResult();

                SampleEncryptDecrypt sampleEncryptDecrypt = new SampleEncryptDecrypt(vault);
                sampleEncryptDecrypt.TestEncryptDecrypt().GetAwaiter().GetResult();

                SampleKeyWrapping keyWrapping = new SampleKeyWrapping(vault);
                keyWrapping.TestKeyWrapping().GetAwaiter().GetResult();

                SampleSimpleSecret sampleSimpleSecret = new SampleSimpleSecret(vault);
                sampleSimpleSecret.TestSampleSimpleSecret().GetAwaiter().GetResult();

                SampleEncryptedSecret sampleEncryptedSecret = new SampleEncryptedSecret(vault);
                sampleEncryptedSecret.TestSampleEncryptedSecret().GetAwaiter().GetResult();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

SampleDigitalSignature.cs:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace ASPNET4YOU.AzureKeyVault
{
    public class SampleDigitalSignature
    {
        private readonly SampleKeyVault vault;
        public SampleDigitalSignature(SampleKeyVault sampleKeyVault)
        {
            vault = sampleKeyVault;
        }

        public async Task TestDigitalSignature()
        {
            string importantDocument = "This is a really important document that I need to digitally sign.";
            byte[] documentDigest = Hash.Sha256(Encoding.UTF8.GetBytes(importantDocument));

            // Positive Signature Verification Test
            byte[] signature = await vault.Sign(vault.CustomerMasterKeyId, documentDigest);
            bool verified = await vault.Verify(vault.CustomerMasterKeyId, documentDigest, signature);

            // Negative Signature Verification Test
            importantDocument = "@This is a really important document that I need to digitally sign.";
            documentDigest = Hash.Sha256(Encoding.UTF8.GetBytes(importantDocument));
            verified = await vault.Verify(vault.CustomerMasterKeyId, documentDigest, signature);
        }
    }
}

Conclusion:

It’s easy to provision HSM backed key vault in cloud but you should do the home work before rolling out production grade vault to store secrets. Check your requirements, verify encryption algorithm and strength are supported, think of governance to control RBAC and key access policy and last but not the least how you are going to monitor activities when someone touches key vault. Do you have to port an existing key from on-premise to cloud? Some vendor product will not allow export keys on your own but vendor may help you to export existing key with a fee. Do you have to generate new key? If so, how will the clients verify unless/until they have the new public key? Key distribution is not as easy as you would think! Your journey is likely be smooth once you have answered all the questions.

Leave a Reply