Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Hosted-services / Azure

Using C# .NET to Read and Write from Azure Key Vault Secrets

4.47/5 (5 votes)
13 Apr 2019CPOL3 min read 92.7K  
How to use C#.NET to read and write from Azure key vault secrets

Introduction

Azure's Key Vault solves a big problem of storing connection strings, passwords and other items with your application. The problem is that using the Key Vault with C# isn't entirely clear on the actual operation.

Background

The Key Vault can be used to store anything you want securely and can be recalled online to be used in your application. While there are firewall rules to lock the service down, that will not be covered here. To learn what can be stored in Key Vault, read this article.

What I wanted was a way to store things like a connection string securely away from my web application. So in this article, I will be covering the secrets section here, but the same process works for Key Vault Certificates and Keys.

Using the Code

The first thing you will need is a Key Vault in Azure. To create the Key Vault, click on the "+ Create Project" in the upper left corner of your portal in https://portal.azure.com.

Image 1

Give the vault a name, it will have to be unique across all of Azure. I recommend using something long but descriptive like KeyVaultAppName.

Image 2

After clicking save and waiting a few moments, you will see a message that the "Deployment Succeeded". You are now able to view the empty Key Vault by clicking on Resources - KeyVaultName.

Image 3

When you click on the Key Vault, along the left side, you will see three items, Keys, Secrets, and Certificates. Click on Secrets.

Image 4

The last thing you will need to do is register the application for authorization in Azure Active Directory. Click on Azure Active Directory under favorites (or search for it if it doesn't exist). Then, click on App Registrations.

Image 5

Create a registration for the Key Vault application:

Image 6

After saving, you will see the Client ID which is actually called "Application ID" in the image below.

Image 7

Finally, you will need to create a key to access this resource. Click on the Keys link to the right in the above image.

Image 8

Provide a name and select a length of time for the key. For this example, I will select never expires.

When you click on save, the value of the key will show. MAKE SURE YOU COPY THIS DOWN, IT WILL BE THE ONLY CHANCE YOU HAVE TO DO SO. This is your ClientSecret.

And then go back into the key vault and apply the permissions to the secrets store. Search and use the name you created above.

Image 9

Now you can create a project in Visual Studio. For this example, I'm creating a console application. Add the nuget packages:

  • Microsoft.Azure.KeyVault
  • Microsoft.Azure.Management.KeyVault
  • Microsoft.IdentityModel.Clients.ActiveDirectory

You are now ready to store information into the "Secrets" in Key Vault. Add the constants and modify the Main() to this:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.KeyVault.Models;
using Microsoft.IdentityModel.Clients.ActiveDirectory;

const string CLIENTSECRET = "XxAg+RRvH0qSrfWmQsP1P3gO9FZ8e7j+8x1foE7ugFc="; 
const string CLIENTID = "cd830ebc-213c-4586-9246-db0f3e238e32";
const string BASESECRETURI = 
    "https://testvaultcp.vault.azure.net"; // available from the Key Vault resource page

static KeyVaultClient kvc = null;

static void Main(string[] args)
{
    DoVault();

    Console.ReadLine();
}

The first method we are going to create is to create an app token to access the Key Vault.

C#
public static async Task<string> GetToken(string authority, string resource, string scope)
{
      var authContext = new AuthenticationContext(authority);
      ClientCredential clientCred = new ClientCredential(CLIENTID, CLIENTSECRET);
      AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);

      if (result == null)
          throw new InvalidOperationException("Failed to obtain the JWT token");

      return result.AccessToken;
}

The DoVault creates, then reads the secrets:

C#
private static void DoVault()
{
     kvc = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken));

     // write
     writeKeyVault();
     Console.WriteLine("Press enter after seeing the bundle value show up");
     Console.ReadLine();

     SecretBundle secret = Task.Run( () => kvc.GetSecretAsync(BASESECRETURI + 
          @"/secrets/" + SECRETNAME)).ConfigureAwait(false).GetAwaiter().GetResult();
     Console.WriteLine(secret.Tags["Test1"].ToString());
     Console.WriteLine(secret.Tags["Test2"].ToString());
     Console.WriteLine(secret.Tags["CanBeAnything"].ToString());

     Console.ReadLine();

}

For the sake of quickness, the above method will wait for the post back / results of the write. After seeing a good write, you can hit enter and have it read from the Key Vault.

I split out the writeKeyVault because it makes it easier to read:

C#
private static async void writeKeyVault()// string szPFX, string szCER, string szPassword)
{
     SecretAttributes attribs = new SecretAttributes
     {
          Enabled = true//,
          //Expires = DateTime.UtcNow.AddYears(2), // if you want to expire the info
          //NotBefore = DateTime.UtcNow.AddDays(1) // if you want the info to 
                                                   // start being available later
     };

     IDictionary<string, string> alltags = new Dictionary<string, string>();
     alltags.Add("Test1", "This is a test1 value");
     alltags.Add("Test2", "This is a test2 value");
     alltags.Add("CanBeAnything", "Including a long encrypted string if you choose");
     string TestName = "TestSecret";
     string TestValue = "searchValue"; // this is what you will use to search for the item later
     string contentType = "SecretInfo"; // whatever you want to categorize it by; you name it

     SecretBundle bundle = await kvc.SetSecretAsync
        (BASESECRETURI, TestName, TestValue, alltags, contentType, attribs);
     Console.WriteLine("Bundle:" + bundle.Tags["Test1"].ToString());
}

When it comes to reading this secret later, you will use the "TestName" parameter above.

After running the code, let's look at the Azure Key Vault resource.

Image 10

Click on the newly created secret:

Image 11

Select the current version and click on the tags to see what was saved:

Image 12

Points of Interest

There really isn't a lot of magic to this. It was a lot easier than I was thinking it was but there was little to no code out there to demo how this works. I hope this helps you save a little time.

History

  • 4/12/2019: Original post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)