tl;dr
I encountered a hurdle when adding a multi-line PGP private key to Azure Key-Vault’s secrets through the UI due to its limitations with multi-line secrets. After initial decryption failures and a lot of time spent on investigating the root cause, the resolution involved using PowerShell and the Azure CLI.
The process includes adjusting newline characters in a text editor (if the secret is not already in multi-line format) and utilizing the CLI to securely upload multi-line secrets to Azure Key-Vault. Head to the “Solution” or “Conclusion” section for the process.
Background
Here is the Wikipedia link to PGP.
PGP or Pretty Good Privacy is a common encryption technique used to encrypt all types of sensitive files sent over the network. If you work in a data team, chances you would have encountered one of these files, ending with a .gpg extension that needs to be decrypted first before being parsed out.
PGP
PGP is just a typical asymmetric cryptographic algorithm. In short, data is encrypted using the receivers public key and decrypted by the receiver using the private key that is mathematically related to the public key, along with a passphrase to unlock the key. One of the properties that makes PGP secure is that it uses a MULTI-LINE private key. This leads me to the heart of today’s discussion and the challenge I encountered when decrypting a bank file when the private key is securely housed in Azure Key-Vault.
Problem
During local testing, I created a short-lived PGP key-pair and encrypted the file using the public key. For more details on using the gpg package to encrypt and decrypt files, refer to my other blog post here: https://www.tarunrajnish.com/blog/simplest-way-to-generate-pgp-keys-and-encrypt-a-file-using-powershell/
In order to test decryption, I wrote a stand alone Python script and pasted the contents of the corresponding private key in my code.
NOTE: DO NOT RESUSE THESE KEYS AS THEY ARE JUST MEANT FOR TESTING, AND PRODUCTION KEYS SHOULD NEVER HAVE TOUCHED YOUR CODEBASE.
When pasted, newlines are substituted with \n's
by VS Code. This works find when decrypting with the PGPy library as the library is smart enough to recognize these newlines. I figured my testing here was done and the same could be replicated on our test environment which is hosted in Azure.
I went through the same procedure and pasted the private key as an Azure Key-Vault secret, so that it could be referenced as an environment variable in our deployed Function App. However, I was soon confronted with exceptions indicating that the decryption process had failed. Despite my efforts to troubleshoot, I was at a standstill and could not figure out why decryption wasn’t working through the portal.
I realized there were two problems I was dealing with:
1. PGP keys need to be multi-line and Azure Key-Vault Secrets do not handle these well when pasted from clipboard.
2. I needed to be using the Azure CLI when uploading multi-line keys as going through the UI does not work well.
Solution
Navigating this issue involves several steps. Firstly, I discovered that Azure Key-Vault does not support the input of multi-line secrets directly through its user interface. This crucial piece of information is somewhat concealed; it only becomes apparent if you hover over the ‘i’ icon next to the secret values field (see screenshot below), a subtle detail that I believe deserves more prominent visibility.

As it stands, Azure recommends the use of PowerShell to manage multi-line secrets, providing a practical workaround for this limitation.
Here is the process I typically follow in order to upload multi-line secrets into Azure Key-Vault such as GPG Private Keys. This process covers two parts – making sure the key is the expected multi-line format, and actually uploading the key itself. Depending on your use-case, please reference the concerned section.
- Copy the key into a temporary Notepad++ file or any other rich text editor (disconnected from the internet)
- Make sure the encoding is set to UTF 8 and UNIX (LF)!
- If your key is in single line, you want to convert it into multiline before uploading:
- Press
Ctrl+H
to open the “Replace” dialog - In the “Find what” box, enter
\\n
(The double backslash is used to escape the backslash character) - In the “Replace with” box, enter
\r\n
for Windows newline or just\n
for a Unix/Linux newline.
- Press
- If you did that correctly, your secret should look to be in the proper multi-line format beginning with
----BEGIN PGP PRIVATE KEY BLOCK----
in the first line and then a newline below it - Now save the file with some name say
secretfile.asc
- Open PowerShell in administrator mode
- Sometimes, your key might not be properly ASCII-armored. On PowerShell, you can run this command to armor it:
gpg --armor --export <key_id> > armored_secretfile.asc
- Assuming you have Azure CLI installed, and you have logged in
(az login --use-device-code)
, you must run:az keyvault secret set
--vault-name "key-vault-name"
--name "secret-name" --file "
armored_secretfile
.asc" - If you refresh you Key-Vault, you should see this new key with the name you provided
- Remember to delete the secret file from your machine as a security measure
- Sometimes, even doing this corrupts the key while uploading or Key-Vault is not table to decipher newlines. Another way you can try is to delete or replace newlines:
Delete
(Get-Content -Path 'public.asc') -Join | Out-File -Path 'new_public.asc'
# OR
(GC 'public.asc') -Join > 'new_public.asc'
Replace
(Get-Content -Path '.\public_test.asc') -Join "\n"
# OR
(GC 'public.asc') -Join "\n"
Reference: https://wind010.hashnode.dev/gpgpgp-key-generation-and-management - Upload using the
az keyvault secret set
command above and try decrypting through your application.
Conclusion
As of 2023-10-18, Azure Key-Vault does not allow multi-line secrets to be pasted from clipboard as a secret value. You will need to use the Azure CLI on a Terminal or PowerShell in order to accomplish this task. Save the secret in a text file on your machine, use a text editor to replace all \\n
with \r\n
, and then use the command az keyvault secret set --name "secret-name" --value "$(cat .\secretfile.asc)" --vault-name "key-vault-name"
to push the secret to Key-Vault.