Get started with Azure Key Vault certificates

Introduction

Use this tutorial to help you get started with Azure Key Vault Certificates to store and manage x.509 certificates in Azure. It walks you through the process of using Azure PowerShell to create a certificate self-signed or signed by supported certificate authority, import a certificate and retrieve the certificate with or without private key to use it with an Azure application.

Estimated time to complete: 30 minutes
Note: This tutorial does not include instructions for how to write the Azure application that will consume the certificate and how to authorize this application to use certificate in the key vault.

As usual, we value your input so please take a moment to join our advisory board, send us private feedback,and/or visit our forum.

For overview information about Azure Key Vault, see What is Azure Key Vault? and Get started with Azure Key Vault

Prerequisites

To complete this tutorial, you must have the following:

  • An existing key vault that you have been using.

  • A pfx file stored on your hard drive.

  • Azure PowerShell, minimum version of 2.1.0.

    To install Azure PowerShell and associate it with your Azure subscription, see How to install and configure Azure PowerShell. If you have already installed Azure PowerShell and do not know the version, from the Azure PowerShell console, type (Get-Module azure -ListAvailable).Version.

This tutorial is designed for Azure PowerShell beginners who understand the basic concepts, such as modules, cmdlets, and sessions but it also assumes that you are familiar with Azure Key Vault and have gone through Get started with Azure Key Vault.

Connect to your subscriptions

Start an Azure PowerShell session and sign in to your Azure account with the following command:

 Login-AzureRmAccount

In the pop-up browser window, enter your Azure account user name and password. Azure PowerShell will get all the subscriptions that are associated with this account and by default, uses the first one. If you have multiple subscriptions, you might have to specify a specific one that was used to create your Azure Key Vault. Type the following to see the subscriptions for your account:

 
Get-AzureRmSubscription

Then, to specify the subscription that's associated with your key vault, type:

 Set-AzureRmContext -SubscriptionId <subscription ID>

For more information about configuring Azure PowerShell, see How to install and configure Azure PowerShell.

Set the key vault

In our first getting started tutorial, our key vault name was ContosoKeyVault, so we'll continue to use that name and store the details into a variable named vaultName and also set the name for certificate created in the end as ContosoFirstCertificate

 
$vaultName = 'ContosoKeyVault'
$certificateName = 'ContosoFirstCertificate'

Permission to certificates

A newly created Key Vault by default has following permissions set for the creator of the vault:

Keys: get, create, delete, list, update, import, backup,
Secrets: 'all'
Certificates: ‘all’

A vault which was created before the introduction of certificates won’t have any permissions. And in this exercise we are using a previously created key vault and hence, the user would need to set explicit permissions. Type following to give permissions for all operations:

 
Set-AzureRmKeyVaultAccessPolicy -VaultName $vaultName -UserPrincipalName ‘patti.fuller@contoso.com' -PermissionsToCertificates all

PermissionsToCertificates can also be set selectively by allowing only certain operations on the certificates. The list of operations on which permissions can be set are ‘Get, Delete, List, Create, Import, ManageContacts, GetIssuers, ListIssuers, SetIssuers and ‘all’.

Create certificate

Import an existing certificate to key vault

To import an existing certificate, you must have the certificate in a .PFX or PEM file format. If necessary, export an installed certificate with the private key (.PFX format) and a strong password, and save your certificate to your C:\ drive in a file named clientcert.pfx that you want to upload to Azure Key Vault. Type the following to set the variable securepfxpwd for a password of 123 for the .PFX file:

 
$securepfxpwd = ConvertTo-SecureString –String '123' –AsPlainText –Force

Then type the following to import the certificate from the .PFX file, which imports the certificate and monitors the lifetime of the certificate in the Key Vault service:

 
$cer = Import-AzureKeyVaultCertificate -VaultName $vaultName -Name $certificateName -FilePath 'c:\clientcert.pfx' -Password $securepfxpwd

You can now reference this certificate that you created or uploaded to Azure Key Vault, by using its URI. Use https://ContosoKeyVault.vault.azure.net/certificates/ContosoFirstCertificate to always get the current version, and use https://ContosoKeyVault.vault.azure.net/certificates/ContosoFirstCertificate/24bb21dacfad4f178e3d00e9dd54c034 to get this specific version.
If you want to retrieve the pfx back i.e. the private key of the certificate then you use https://ContosoKeyVault.vault.azure.net/secrets/ContosoFirstCertificate to get the current version and use
https://ContosoKeyVault.vault.azure.net/secrets/ContosoFirstCertificate/24bb21dacfad4f178e3d00e9dd54c034

Create a self-signed certificate in key vault

To create certificates in key vault you will first create the certificate policy.

 
$policy = New-AzureKeyVaultCertificatePolicy   -SubjectName "CN=www.contoso.com"   -IssuerName Self   -ValidityInMonths 12

Type following to add a Self-Signed Certificate and use the above policy to be applied to create the certificate

 
Add-AzureKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $policy 

Enroll programmatically from Public CA (Certificate Authority)

Azure Key Vault supports enrollment of certificates from Public CA such as DigiCert, and GlobalSign. Azure Key Vault goes on behalf of the user to enroll for certificates from one of the above issuers. In this process Issuer needs to authenticate the entity requesting the certificate and also authorize to receive the requested certificate. Each Issuer requires different set of information to do so and this needs to be set once in the Key Vault.

If you select DigiCert to be your certificate authority or Issuer to issue certificates then go through these one-time setup steps to configure DigiCert as one of the Issuer in your vault.

Note: Customer will need to have an existing account or go here to create one with DigiCert and get domains pre-vetted

 
#Create an organization for the issuer
$orgIdentifier = "111111"   
$org = New-AzureKeyVaultCertificateOrganizationDetails -Id $orgIdentifier

$apiKey = "111111111" 
$secureApiKey = ConvertTo-SecureString $apiKey -AsPlainText -Force
$accountId = "1111111"
$issuerName = "digiCert01"
 
#Set the relation with the Public CA (DigiCert) for cert issuance
Set-AzureKeyVaultCertificateIssuer -VaultName $vaultName -IssuerName $issuerName -IssuerProvider DigiCert -AccountId $accountId -ApiKey $secureApiKey -OrganizationDetails $org

If you select GlobalSign to be your Issuer then go through these one-time setup steps to configure GlobalSign as one of the Issuer in your vault.

Note: Customer will need to have an existing account or go here to create one with GlobalSign and get your domains pre-vetted

 
#Create an administrator for the issuer (GlobalSign needs to receive Administrator details in the certificate request)
$firstName = "Patti"
$lastName = "Fuller"
$phoneNumber = "4250000000"
$emailAddress = "patti. fuller@contoso.com"
$admin = New-AzureKeyVaultCertificateAdministratorDetails -FirstName $firstName -LastName $lastName -PhoneNumber $phoneNumber -EmailAddress $emailAddress

#Create an organization for the issuer
$org = New-AzureKeyVaultCertificateOrganizationDetails -AdministratorDetails $admin

#Set the relation with the Public CA (GlobalSign) for cert issuance
$apiKey = "Passw0rd!"
$secureApiKey = ConvertTo-SecureString $apiKey -AsPlainText -Force
$accountId = "PAR1000_kvissuer"
$issuerName = "globalsign01"

Set-AzureKeyVaultCertificateIssuer -VaultName $vaultName -IssuerName $issuerName -IssuerProvider GlobalSign -AccountId $accountId -ApiKey $secureApiKey -OrganizationDetails $org

Create the certificate policy similar to creating the template that defines what needs to be in the certificate (SubjectName, SAN etc.), when to renew the certificate and from which Issuer the certificate is to be issued.

 
$policy = New-AzureKeyVaultCertificatePolicy -SecretContentType application/x-pkcs12 -SubjectName "CN=contoso.com" -ValidityInMonths 12 -IssuerName $issuerName -RenewAtNumberOfDaysBeforeExpiry 60

Request for a certificate based on the above set policy

 
Add-AzureKeyVaultCertificate -VaultName $vaultName -CertificateName $certificateName -CertificatePolicy $policy

Certificate enrollment in Key Vault is an asynchronous process. The Add-AzureKeyVaultCertificate will return back an operation object which will indicate the status of enrollment. You can poll the creation of Certificate till the status is returned as complete.

 
Get-AzureKeyVaultCertificateOperation -VaultName $vaultName -Name $certificateName

Once the certificate is created you can view at the newly issued certificate details by following cmdlet

 
Get-AzureKeyVaultCertificate -VaultName $vaultName -Name $certificateName

Create a certificate manually and get signed by a CA

Azure Key Vault supports to create the certificate signing request with private-public key pair and get it signed by any Certificate Authority of your choice. It could be internal enterprise CA or external public CA.

First create the certificate policy. Key Vault will not enroll or renew the certificate from the Issuer on behalf of the user as CA chosen in this scenario is not a supported one and hence the IssuerName is set to Unknown.

 
$manualPolicy = New-AzureKeyVaultCertificatePolicy -SubjectName "CN=www.contosoHRApp.com" -ValidityInMonths 1  -IssuerName Unknown

Create the certificate signing request

 $certificateOperation = Add-AzureKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $manualPolicy
$certificateOperation.CertificateSigningRequest

The $certificateOperation.CertificateSigningRequest is the base4 encoded certificate signing request for the certificate. You can take this blob and dump into Issuer’s certificate request website or use tools such as certreq or openssl to get the certificate request signed and complete the process of generating a certificate.

After the certificate request has been signed by the Issuer, you can bring back the signed certificate usually a file with .cer extension and merge it with the initial private-public key created in Azure Key Vault

 
Import-AzureKeyVaultCertificate -VaultName $vaultName -Name $certificateName -FilePath C:\test\OutputCertificateFile.cer

Retrieve pfx file & add password back

A typical scenario is that the application would need to pull the pfx of the certificate to the machine where it is going to consume the certificate. Here is an example on how an application can retrieve the pfx from Azure Key Vault to consume it.

 
$secretName = "TestCert"
$kvSecret = Get-AzureKeyVaultSecret -VaultName $vaultName -Name $secretName
$kvSecretBytes = [System.Convert]::FromBase64String($kvSecret.SecretValueText)
$certCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$certCollection.Import($kvSecretBytes,$null,[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
 

If the certificate file needs to be stored on the hard disk then it is good practice to encrypt it with a password.

 
#Get the file created
$password = '******'
$protectedCertificateBytes = $certCollection.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $password)
$pfxPath = [Environment]::GetFolderPath("Desktop") + "\MyCert.pfx"
[System.IO.File]::WriteAllBytes($pfxPath, $protectedCertificateBytes)

Get public portion of Certificate from Certificates Endpoint

Type following to retrieve the certificate or the public portion and store in a file with *.cer extension.

 
$cert = Get-AzureKeyVaultCertificate -VaultName $vaultName -Name $certificateName
$filePath = [Environment]::GetFolderPath("Desktop") + "\MyCert.cer"
$certBytes = $cert.Certificate.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Cert)
[System.IO.File]::WriteAllBytes($filePath, $certBytes)

Listing all the certificates from the management endpoint

For management purposes, you would want to know the certificates in your key vault and related information about it. You would retrieve these information by running following queries as below:

 
Get-AzureKeyVaultCertificate –VaultName $vaultName 

Renewal of certificates

Azure Key Vault certificates are auto renewed as per the configured certificate policy. Certificate policy is set to either say how many days before expiry do you want to renew the certificate or at what percentage of the lifetime of the certificate. And the policy also needs to have the Issuer value set to a supported Certificate Authority. In case where Certificate Authority needs authorization and authentication details then those should be set while adding the Issuer to the key vault.

Auto-renewal of certificates can fail due to misconfigured values or it can fail due to lack of funds and at times lack of incomplete vetting of domains. In any of the cases the Azure Key Vault Certificate Contact gets notified with the error message. You can choose to rectify the misconfigured values or add the required funds to your contract so that Azure Key Vault can go ahead and re-attempt the renewal. There will be few instances where Azure key Vault will notify the customer that it is better to manually enroll for the certificate mainly when it is very close to expiry. In such cases, you should go through and add a certificate using one of the above options.

Other Azure PowerShell Cmdlets

Few other commands that you might find useful for managing Azure Key Vault Certificate are:

  • Add-AzureKeyVaultCertificateContact -VaultName $vaultName -EmailAddress "patti.fuller@contoso.com” The Add-AzureKeyVaultCertificateContact cmdlet adds a contact to an Azure Key Vault for certificate notifications. The contact receives updates about events such as certificate close to expiry, certificate renewed, and so on. These events are determined by the certificate policy.
  • Stop-AzureKeyVaultCertificateOperation -VaultName $vaultName -Name $certificateName –Force This cmdlet cancels the certificate operation in process on the $certificateName object.
  • Remove-AzureKeyVaultCertificate -VaultName $vaultName -Name $certificateName Example how to remove a specific certificate.

Next steps

For a list of the latest Azure PowerShell Certificate cmdlets for Azure Key Vault, see Azure Key Vault Cmdlets
For programming references, see the Azure Key Vault developer's guide.