Export an App Service certificate to a pfx file with PowerShell

In order to debug a webjob running in an Azure App Service and accesses a service using a certificate, I needed to create a local copy of the certificate to be able to run the webjob on a local machine. The Azure portal unfortunately only provides these options:

  1. Import an existing App service certificate
  2. Upload a certificate
  3. Delete a certificate

So there is no option to download a certificate. But this can be used using PowerShell and the AzureRM module.

First, we’ll need to set a few variables with the data required to get the certificate:

$azureLoginEmailId = "me@benohead.com"
$subscriptionName = "mysubscriptionname"
$resourceGroupName = "myresourcegroupname"
$certificateName = "nameofthecertificateiwanttodownload"
$pfxPassword = "mygreatpassword"

We’ll later use $pfxPassword to set a password in the created PFX file.

Then I need to login into Azure to be able to access the resources:

Login-AzureRmAccount

You will see a popup where you can enter your credentials.

Then you need to select the appropriate subscription:

Select-AzureRmSubscription -SubscriptionName $subscriptionName

Now, we’re ready to access the certificate resource which can be used to get the actual certificate from the key vault:

$certificateResource = Get-AzureRmResource -ResourceName $certificateName -ResourceGroupName $resourceGroupName -ResourceType "Microsoft.Web/certificates" -ApiVersion "2015-08-01"

The returned resource object has next to the location, name, ID, type and resource group name also a Properties member which contains details about the certificate:

  • subjectName
  • hostNames
  • issuer
  • issueDate
  • expirationDate
  • thumbprint
  • keyVaultId
  • keyVaultSecretName
  • keyVaultSecretStatus
  • webSpace

All the pieces of information we need to retrieve the certificate from key vault are encoded in the keyVaultId except the keyVaultSecretName (which is also in the list above):

/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/xxxxx/providers/microsoft.keyvault/vaults/xxxxx

So by splitting it to an array using / as a separator, you get resource group name for the key vault in the 5th element from the end and the key vault name in the last element.

So you can extract them like this:

$keyVaultId = $certificateResource.Properties.keyVaultId
$keyVaultData = $keyVaultId.Split("/")
$keyVaultDataLength = $keyVaultData.Length
$keyVaultName = $keyVaultData[$keyVaultDataLength - 1]
$keyVaultResourceGroupName = $keyVaultData[$keyVaultDataLength - 5]

You also get the secret name like this:

$keyVaultSecretName = $certificateResource.Properties.keyVaultSecretName

Now we can grant our user┬ápermissions to perform a “get” operation on the key vault:

Set-AzureRmKeyVaultAccessPolicy -ResourceGroupName $keyVaultResourceGroupName -VaultName $keyVaultName -UserPrincipalName $azureLoginEmailId -PermissionsToSecrets get

And you can fetch the secret containing the certificate:

$keyVaultSecret = Get-AzureKeyVaultSecret -VaultName $keyVaultName -Name $keyVaultSecretName

This secret contains a Base64 representation of the certificate which you can convert back to a certificate object using:

$pfxCertObject=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList @([Convert]::FromBase64String($keyVaultSecret.SecretValueText),"", [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)

Now, the only step left is to write the certificate to a local PFX file:

[io.file]::WriteAllBytes(".\appservicecertificate.pfx", $pfxCertObject.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $pfxPassword))

And there you are !

If you have found this page, you probably have also seen a couple of MSDN blog entries about a similar topic:

That’s also where I started but since I had to adapt the code from these two blog entries, I decided to document it in this blog post. Hope this helps !