Clippy will take over your certificates

How to export an App Service Certificate from Azure?

4 min read.

Azure offers this great offering that is in my mind underutilized still – managed certificates that they’ll renew for you. While the offering is called Azure App Service Certificates, they are not only limited to being used in App Services.

Their biggest strengths lie in their ease of use, automation, and integration with different Azure services. These certs are automatically renewed, eliminating the need for manual certificate management. And if the renewal fails, you’ll get a notification (at the last moment, but still – you have a fighting chance to do something before they expire!)

They also seamlessly integrate with custom domains and Azure Key Vault for secure key storage. This simplifies the process of securing web apps, enhances security, and ensures that applications stay up-to-date with the latest security standards without manual intervention.

But what if you need that managed certificate somewhere else? Like, just for an imaginary argument, your locally running Kubernetes certificate?

Well, if no integration to Azure Key Vault has been built, you’ll need to export the certificate from Azure or Azure Key Vault.

Solution

There’s essentially 2 entirely different ways to do this: using the UI or by scripting.

I’ll explain the one using the UI in a how-to below, but if you want to use a PowerShell script instead, I’ll have a couple of options in copy-pasteable format at the bottom of the page ☺

So, let’s get to it!

Time needed: 10 minutes

How to export an app service certificate on Azure Portal?

  1. Navigate to your App Service Certificate on Azure Portal

    We’ll start by finding your App Service Certificate on your Azure Portal.

    Accessing "App Service Certificates" on Azure Portal

  2. Select Export Certificate

    After selecting your certificate from the list, you can select “Export Certificate” on the left hand side navigation.

    Selecting "Export Certificate" for your Azure App Service Certificate.

  3. Click the link that’ll take you to the certificate in Azure Key Vault

    Select “Open Key Vault Secret” under “Download certificate from Key Vault”. You’ll be taken to the certificate’s entry in Azure Key Vault (that’s where it’s actually stored).

  4. Select the latest version of the certificate

    Select “current” version for the entry in Azure Key Vault. It’s the latest one.

    Select "current" version for the entry in Azure Key Vault. It's the latest one.

  5. Click “Download as a certificate”

    Select “Download as a certificate” on the secret details page in Azure Key Vault.

    Select "Download as a certificate" on the secret details page in Azure Key Vault.

    And you should simply receive and .pfx file with a pretty long name. It’ll be password protected with an empty password.

  6. (OPTIONAL) Export the .cer and .key files from your new .pfx file

    The short version:

    openssl pkcs12 -in .\my.pfx -out my.cer -clcerts
    openssl pkcs12 -in .\my.pfx -nocerts -out my-encrypted.key

    The longer explanation is here:
    How to export a certificate and a private key from a .pfx using OpenSSL?

And there you have it! But if you don’t want to use the graphical user interface (Azure Portal) for the process, take a look at the scripts shared below.

References and appendices

A couple of useful links:

Below are the different scripted ways to export the certificate!

Appendix 1: PowerShell script to export an App Service Certificate from Azure

You actually have at least 2 different options, shared by Microsoft and offered below for your convenience, for exporting an Azure App Service certificate using PowerShell.

Lengthy custom commandlet built with Az module

This one was first shared around 2017 but has probably been updated since, since it’s using the more modern PowerShell module simply called “Az”.

Function Export-AppServiceCertificate
{
  ###########################################################

  Param(
  [Parameter(Mandatory=$true,Position=1,HelpMessage="ARM Login Url")]
  [string]$loginId,

  [Parameter(Mandatory=$true,HelpMessage="Subscription Id")]
  [string]$subscriptionId,

  [Parameter(Mandatory=$true,HelpMessage="Resource Group Name")]
  [string]$resourceGroupName,

  [Parameter(Mandatory=$true,HelpMessage="Name of the App Service Certificate Resource")]
  [string]$name
  )

  ###########################################################

  Connect-AzAccount
  Set-AzContext -Subscription $subscriptionId

  ## Get the KeyVault Resource Url and KeyVault Secret Name were the certificate is stored
  $ascResource= Get-AzResource -ResourceId "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.CertificateRegistration/certificateOrders/$name"
  $certProps = Get-Member -InputObject $ascResource.Properties.certificates[0] -MemberType NoteProperty
  $certificateName = $certProps[0].Name
  $keyVaultId = $ascResource.Properties.certificates[0].$certificateName.KeyVaultId
  $keyVaultSecretName = $ascResource.Properties.certificates[0].$certificateName.KeyVaultSecretName

  ## Split the resource URL of KeyVault and get KeyVaultName and KeyVaultResourceGroupName
  $keyVaultIdParts = $keyVaultId.Split("/")
  $keyVaultName = $keyVaultIdParts[$keyVaultIdParts.Length - 1]
  $keyVaultResourceGroupName = $keyVaultIdParts[$keyVaultIdParts.Length - 5]

  ## --- !! NOTE !! ----
  ## Only users who can set the access policy and has the the right RBAC permissions can set the access policy on KeyVault, if the command fails contact the owner of the KeyVault
  Set-AzKeyVaultAccessPolicy -ResourceGroupName $keyVaultResourceGroupName -VaultName $keyVaultName -UserPrincipalName $loginId -PermissionsToSecrets get
  Write-Host "Get Secret Access to account $loginId has been granted from the KeyVault, please check and remove the policy after exporting the certificate"

  ## Getting the secret from the KeyVault
  $secret = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $keyVaultSecretName -AsPlainText
  $pfxCertObject= New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList @([Convert]::FromBase64String($secret),"",[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
  $pfxPassword = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 50 | % {[char]$_})
  $currentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
  [Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
  [io.file]::WriteAllBytes(".\appservicecertificate.pfx",$pfxCertObject.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12,$pfxPassword))

  ## --- !! NOTE !! ----
  ## Remove the Access Policy required for exporting the certificate once you have exported the certificate to prevent giving the account prolonged access to the KeyVault
  ## The account will be completely removed from KeyVault access policy and will prevent to account from accessing any keys/secrets/certificates on the KeyVault, 
  ## Run the following command if you are sure that the account is not used for any other access on the KeyVault or login to the portal and change the access policy accordingly.
  # Remove-AzKeyVaultAccessPolicy -ResourceGroupName $keyVaultResourceGroupName -VaultName $keyVaultName -UserPrincipalName $loginId
  # Write-Host "Access to account $loginId has been removed from the KeyVault"

  # Print the password for the exported certificate
  Write-Host "Created an App Service Certificate copy at: $currentDirectory\appservicecertificate.pfx"
  Write-Warning "For security reasons, do not store the PFX password. Use it directly from the console as required."
  Write-Host "PFX password: $pfxPassword"    
}

And then run it somewhat like this:

cd C:\projects\MyBeautifulProjectFolder\
Export-AppServiceCertificate -loginId "[email protected]" -subscriptionId "bbb4f15b-f62e-af02-890f-16075e68dccc" -resourceGroupName "Contoso-core" -name "contoso-cert"

This script was originally from here: https://azure.github.io/AppService/2017/02/24/Creating-a-local-PFX-copy-of-App-Service-Certificate.html

A short and sweet script using AzureRM

This script published in 2023 is using the legacy module AzureRM for whatever reason. But it’s short and sweet, so I think it’s worth sharing:

#Connect to Azure and select subscription
Login-AzureRmAccount
Select-AzureRMSubscription -SubscriptionName "<name of subscription containing keyvault>"
   
#Obtain the secret from keyvault
$vaultName = '<name of Keyvault>'
$secretName = '<name of secret containing certificate>'
$certString = Get-AzureKeyVaultSecret -VaultName $vaultName -Name $secretName
   
#Create a PFX from the secret and write to disk
$kvSecretBytes = [System.Convert]::FromBase64String($certString.SecretValueText)
$certCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$certCollection.Import($kvSecretBytes,$null,[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
$password = '<required password for PFX>'
$protectedCertificateBytes = $certCollection.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $password)
$pfxPath = "C:\temp\$secretName.pfx"
[System.IO.File]::WriteAllBytes($pfxPath, $protectedCertificateBytes)

It’s from here: https://techcommunity.microsoft.com/t5/apps-on-azure-blog/export-app-service-certificate-and-set-up-a-password/ba-p/3731559

mm
0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments