Accessing Azure Key Vaults Using Certification

In the old days, we used to access the Azure Key Vaults using the Vault URL and its Secret Key, we were placing this in the config file and going from there.

Placing sensitive information in the config file is a bad idea, it may cause a security breach and loss of data.

This article will explain how we can access the Azure Key Vault information using Self-signed certification, which involves the below steps.

  1. Create self-signed certificate
  2. Create a private key for the certificate
  3. Create Azure AD App
  4. Assign certificate to Azure AD APP
  5. Provide permission to Azure AD app in Key Vault
  6. Register/publish the certificate on a local machine (In the current scenario we are storing the certificate in a local machine, we can register the certificate in Azure app service also)

Coming to actual implementation.

Step 1. Creating Self-Signed certificate

Open Visual Studio command prompt as administrator.

Visual Studio

Execute the below command to create the certificate. It will prompt for the private key password; provide the same password in all the places.

makecert -sv Mykey.pvk -n "cn=DEVCertificate" DEVCertificate.cer -b <<StartDate>> -e <<End Date>> -r

 Command

OK

Step 2. Create a private key for the certificate

Use the below command to create a private certificate. Here, we need to pass the certificate name and desired pfx file name and private key.

pvk2pfx -pvk Mykey.pvk -spc DEVCertificate.cer -pfx DEVCertificate.pfx -po <<Password>>

 Create

It created both, public and private, certificates.

Certificates

Step 3 & 4. Create an Azure AD App and Assign a certificate

The below PowerShell script will import the certificate, create an Azure AD App, and assign the certificate to that app.

$certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$certificateFilePath = "C:\DEVCertificate.cer"
$certificate.Import($certificateFilePath)
$rawCertificateData = $certificate.GetRawCertData()
$credential = [System.Convert]::ToBase64String($rawCertificateData)
$adApplication = New-AzureRmADApplication -DisplayName "DevClientApp" -HomePage "http://www.DevClient.com" -IdentifierUris "http://www.DevClient.com" -CertValue $credential -StartDate $certificate.GetEffectiveDateString() -EndDate $certificate.GetExpirationDateString()

App

Settings

Step 4. Provide permission to the Azure AD app

The below script will give permission to the Azure AD App in Azure Key Vault.

$servicePrincipal = New-AzureRmADServicePrincipal -ApplicationId $adApplication.ApplicationId
Set-AzureRmKeyVaultAccessPolicy -VaultName 'RKDevKeyVault' -ServicePrincipalName $servicePrincipal.ServicePrincipalNames[0] -PermissionsToSecrets all -PermissionsToKeys all

AD App

You can get the thumbprint of the certificate by using the Certificate Thumbprint function.

$certificate.Thumbprint

Now, we have done all the necessary configuration for registering the certification with Azure, and created an application to access the key vaults.

Step 5. Register certificate in Local Machine

Open the private certification (.psk file) and follow the below steps to register the certificate on a local machine.

 Local Machine

Select default options provide a private key and finish the wizard, this will register the certificate on a local machine. We can find the registered certificate in MMC (Microsoft Management Console).

Search for MMC and open.

MMC

Open the File menu and click on Add/Remove Snap-in. Select Computer Account and Local Computer to add the certificate section.

Local computer

Azure Key

Open the Certificate folder. You can see all the registered certificates here.

 Certificate folder

Step 6. Creating an application to access the key vaults

Here, I am creating a simple Visual Studio console application for demo purposes.

Create a console application and add the below helper call to the project.

Key vault

AzureKeyVaultCertificationHelper.cs

using Microsoft.Azure.KeyVault;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace KeyVaultCertification
{
    public class AzureKeyVaultCertificationHelper
    {
        public static X509Certificate2 FindCertificateByThumbprint(string thumbprint)
        {
            X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            try
            {
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
                if (col == null || col.Count == 0)
                {
                    throw new Exception("ERROR: Certificate not found with thumbprint");
                }
                return col[0];
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
            finally
            {
                store.Close();
            }
        }
        public static ClientAssertionCertificate AssertionCert { get; set; }
        public static void GetCertification()
        {
            var clientAssertionCertPfx = FindCertificateByThumbprint(ConfigurationManager.AppSettings["ThumbPrint"]);
            AssertionCert = new ClientAssertionCertificate(ConfigurationManager.AppSettings["ClientApplicationId"], clientAssertionCertPfx);
        }
        public static async Task<string> GetAccessToken(string authority, string resource, string scope)
        {
            var context = new AuthenticationContext(authority, TokenCache.DefaultShared);
            var result = await context.AcquireTokenAsync(resource, AssertionCert);
            return result.AccessToken;
        }
        public static string GetKeyVaultSecret(string secretNode)
        {
            var secretUri = string.Format("{0}{1}", ConfigurationManager.AppSettings["VaultUrl"] + "/secrets/", secretNode);
            GetCertification();
            var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken));
            return keyVaultClient.GetSecretAsync(secretUri).Result.Value;
        }
    }
}

Program. cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace KeyVaultCertification
{
    public class Program
    {
        static void Main(string[] args)
        {
            string sourceUrl = AzureKeyVaultCertificationHelper.GetKeyVaultSecret("SourceUrl");
            Console.WriteLine(sourceUrl);
        }
    }
}

Provide certificate Thumbprint, Azure AD App client ID, and Vault URL.

app. config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1"/>
  </startup>
  <appSettings>
    <add key="ThumbPrint" value="4444B4EDC4BFA4444444C44E4FF53B13B444C444"/>
    <add key="ClientApplicationId" value="abcdef-ghij-413e-klmn-1922ff69xyz"/>
    <add key="VaultUrl" value="https://RKkeyvault.azure.net"/>
  </appSettings>
</configuration>

Output

Output


Similar Articles