Accessing Azure Key Vaults Using Certification

In the old days, we used to access the Azure Key Vaults using 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 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 certificate in local machine (In current scenario we are storing certificate in local machine, we can register certificate in azure app service also)

Coming to actual implementation.

Step 1 – Creating Self-Signed Certificate

Open Visual Studio command prompt as administrator.

Azure Key Vaults

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

Azure Key Vaults

Azure Key Vaults

Step 2 – Create 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>>

Azure Key Vaults

It created both, public and private, certificates.

Azure Key Vaults

Step 3 & 4 – Create Azure AD App and Assign certificate

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

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

Azure Key Vaults

Azure Key Vaults

Step 5 – Provide permission to the Azure AD App

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

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

Azure Key Vaults

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

$certificate.Thumbprint

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

Step 6 – Register Certificate in Local Machine

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

Azure Key Vaults

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

Search for MMC and open,

Azure Key Vaults

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

Azure Key Vaults

Azure Key Vaults

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

Azure Key Vaults

Step 7 - Creating Application to access the key vaults

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

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

Azure Key Vaults

AzureKeyVaultCertificationHelper.cs

  1. using Microsoft.Azure.KeyVault;  
  2. using Microsoft.IdentityModel.Clients.ActiveDirectory;  
  3. using System;  
  4. using System.Collections.Generic;  
  5. using System.Configuration;  
  6. using System.Linq;  
  7. using System.Security.Cryptography.X509Certificates;  
  8. using System.Text;  
  9. using System.Threading.Tasks;  
  10.   
  11. namespace KeyVaultCertification  
  12. {  
  13.     public class AzureKeyVaultCertificationHelper  
  14.     {  
  15.         public static X509Certificate2 FindCertificateByThumbprint(string thumbprint)  
  16.         {  
  17.             X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);  
  18.             try  
  19.             {  
  20.                 store.Open(OpenFlags.ReadOnly);  
  21.                 X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);  
  22.                 if (col == null || col.Count == 0)  
  23.                 {  
  24.                     throw new Exception("ERROR: Certificate not found with thumbprint");                      
  25.                 }  
  26.                 return col[0];  
  27.             }  
  28.             catch (Exception ex)  
  29.             {  
  30.                 Console.WriteLine(ex.Message);  
  31.                 return null;  
  32.             }  
  33.             finally  
  34.             {  
  35.                 store.Close();  
  36.             }  
  37.         }  
  38.   
  39.         public static ClientAssertionCertificate AssertionCert { get; set; }  
  40.   
  41.         public static void GetCertification()  
  42.         {  
  43.             var clientAssertionCertPfx = FindCertificateByThumbprint(ConfigurationManager.AppSettings["ThumbPrint"]);  
  44.             AssertionCert = new ClientAssertionCertificate(ConfigurationManager.AppSettings["ClientApplicationId"], clientAssertionCertPfx);  
  45.         }  
  46.         public static async Task<string> GetAccessToken(string authority, string resource, string scope)  
  47.         {  
  48.             var context = new AuthenticationContext(authority, TokenCache.DefaultShared);  
  49.             var result = await context.AcquireTokenAsync(resource, AssertionCert);  
  50.             return result.AccessToken;  
  51.         }  
  52.   
  53.         public static string GetKeyVaultSecret(string secretNode)  
  54.         {  
  55.             var secretUri = string.Format("{0}{1}", ConfigurationManager.AppSettings["VaultUrl"] + "/secrets/", secretNode);  
  56.             GetCertification();  
  57.             var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken));  
  58.   
  59.             return keyVaultClient.GetSecretAsync(secretUri).Result.Value;  
  60.         }  
  61.     }  
  62. }  

Program.cs

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace KeyVaultCertification  
  7. {  
  8.     public class Program  
  9.     {  
  10.         static void Main(string[] args)  
  11.         {  
  12.             string sourceUrl = AzureKeyVaultCertificationHelper.GetKeyVaultSecret("SourceUrl");  
  13.             Console.WriteLine(sourceUrl);  
  14.         }  
  15.     }  
  16. }  

Provide certificate Thumbprint, Azure AD App client id, and Vault URL

app.config

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

Output

Azure Key Vaults