Today, after spending several hours swearing and researching how to import a publicly-issued certificate into Azure Key Vault, I thought I’d share the entire process of how we did it from start to finish so that you can save yourself a bunch of time and get back to working on fun stuff, like spamming your co-workers with Cat Facts. We learned a bunch about the different encoding formats of certificates and some of their restrictions, both within Azure Key Vault as well as with the certificate types themselves. Let’s get started!
Initially, we created an elliptic curve-derived (EC) private key (using elliptic curve prime256v1), and a CSR by doing:
openssl ecparam -out privatekey.key -name prime256v1 -genkey
openssl req -new -key privatekey.key -out request.csr -sha256
making sure to not include an email address or password. I am not actually clear on what the technical reasoning behind this is, but I saw it noted on several sites.
We submitted the CSR to our certificate authority (CA) and shortly thereafter got back a signed PEM file.
We next needed to create a single PFX/PKCS12-formatted, password-protected certificate, so we grabbed our signed certificate (
ServerCertificate.crt) and our CA’s intermediate certificate chain (
Chain.crt) and then did:
openssl pkcs12 -export -inkey privatekey.key -in ServerCertificate.crt -certfile Chain.crt -out Certificate.pfx
But when we went to import it into the Key Vault with the correct password, it threw a general “We don’t like this certificate” error. The first thing we did was check out the provided link and saw that we could import PEM-formatted certificates directly. I didn’t remember this being the case in the past, so maybe this is a new feature?
No problem. We concatenated the certificate and key files into a single, large text file (
echo ServerCertificate.crt >> concat.crt ; echo privatekey.key >> concat.crt) which would create a file called
concat.crt which itself would consist of the
section from the
ServerCertificate.crt file as well as the
-----BEGIN EC PARAMETERS-----
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
-----END EC PRIVATE KEY-----
sections from the
We went to upload
concat.crt to the Key Vault and again were given the same error as before however after re-reading the document, we were disappointed when we saw this quote:
We currently don’t support EC keys in PEM format.Section: Formats of Import we support
It surprises me that Microsoft does not support elliptic curve-based keys in PEM format. I am not aware of any technical limitation on the part of the certificate so this seems very much like a Microsoft-specfic thing, however if anyone is able to provide insight into this, I’d love to hear it.
OK, we’ll generate an 2048-bit RSA-derived key and CSR, and then try again.
openssl genrsa -des3 -out rsaprivate.key 2048
openssl req -new -key rsaprivate.key -out RSA.csr
We uploaded the CSR to the CA as a re-key request, and waited.
When the certificate was finally issued (as
cert.pem), we could now take the final steps to prepare it for upload to the Key Vault. We concatenated the key and certificate together (
echo rsaprivate.key >> rsacert.crt ; echo cert.pem >> rsacert.crt) and went to upload it to the Key Vault.
And yet again, it failed. After a bunch of researching on security blogs and StackOverflow, it turns out that the default output format of the private key is PKCS1, and Key Vault expects it to be in PKCS8 format. So now time to convert it.
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in rsaprivate.key -out rsaprivate8.key
Finally, we re-concatenated the
cert.pem files into a single
rsacert8.crt file (
echo rsaprivate8.key >> rsacert8.crt ; echo cert.pem >> rsacert8.crt) which we could import into Key Vault.
We now have our SSL certificate in our HSM-backed Azure Key Vault that we can apply to our various web properties without having to store the actual certificate files anywhere, which makes our auditors very happy.