Azure Key Vault - Certificates and private keys

Today I helped a customer confused about how to properly download a certificate from Key Vault that contains both the public and private keys.  The current method for downloading a certificate will retrieve only the public key.  Having both parts of the certificate is essential for SSL binding and is necessary for situations such as sending a client certificate for authentication.

As I have shown in previous posts, but perhaps not described fully, is that the necessary method for retrieving the certificate with both keys is to download it as a secret. It does not mean that you re-upload the certificate into the Secrets blade.  It means that you leave the certificate exactly where it is, yet when downloading the certificate as a secret, use the secrets endpoint.  Here's my example:

First, let's establish that I have a certificate, listed as a certificate, in my Key Vault:

The certificate "KVExplorerCom" is an App Service Certificate uploaded to a Key Vault named "kvexplorer".  

Using C# to download the certificate as a certificate reveals the following information:

First, I get a really nice CertificateBundle object displaying the downloaded certificate in a pleasant form.  The values are readily observable.  Another nice and important feature is a byte array called Cer which describes the certificate, and I can use this to convert to an X509 certificate, which I do in the next line of code.  Let's look at that now...

Now that I've created an X509 certificate in memory, examining it seems to go well, until you see that there's no Private Key.  That's the part many applications require for proper SSL binding.  This makes more sense when you realize that the public key for a certificate has a file extension which is ".cer", while the private extension is ".key".  

You can see more about the widely-used certificate file extensions here.

Now let's see what happens when I download the certificate as a secret.

This time I get a SecretBundle object, with the Content-Type set to a certificate, and the Value which is my secret in Base-64 encoding.  Once I Base-64 decode the Value of this secret, I can then convert it to a complete X509 certificate, with public key:

Final note about this downloaded certificate:  if you save the X509 certificate as a PFX, it will not have a password.  This is because of the way that Key Vault stores the certificate internally.  You can see my previous post for instructions on how to download the certificate using Powershell and simultaneously generate a password for it as it's being written to disk.

I am providing feedback to our product team that this is a confusing mechanism in Key Vault and could use improvement.  

Please follow us on Twitter and retweet!
@WinDevMatt @AzIdentity



Comments (1) -

Marc Scheuner 3/25/2020 9:24:42 AM

GOSH !! Why is this so darn convoluted?? Why can't there just be a parameter  "includePrivate: bool" on the "GetCertificateAsync" call to tell keyvault if you need just the public, or public and private parts of your certificate?

You store a certificate - but to get it, you need to fetch a secret .... that's just all wrong, and violates the Basic Principle Of Least Surprise!

MS, if you're listening - this API really needs a bit more work to make it more approachable to novice Azure devs!!

Add comment