I have 2 approaches to do the same thing, but Azure has deprecated the one that works, and the other method doesn't work.
The approach that works, but is deprecated:
I store my PFX in Azure Key Vault Secrets. (when I create the secret I see a warning stating that this feature is deprecated)
and use the following code to retrieve it to create my certificate:
SecretBundle secret = await keyVaultClient.GetSecretAsync(keyVaultUrl, "MyCert-Secret");
X509Certificate2Collection exportedCertCollection = new X509Certificate2Collection();
exportedCertCollection.Import(Convert.FromBase64String(secret.Value));
X509Certificate2 certFromSecret = exportedCertCollection.Cast<X509Certificate2>().Single(s => s.HasPrivateKey);
credits to this answer
I'm able to use this certificate to host and access my application successfully.
The approach that doesn't work, but I should be using:
I store my certificate in the Azure Key vault Certificates
and use the following code to retrieve it and create the X509Certificate2:
CertificateBundle certificateBundle = await keyVaultClient.GetCertificateAsync(keyVaultUrl, "MyCert-Certificate");
X509Certificate2 certFromCertificate = new X509Certificate2(certificateBundle.Cer);
The problem with this approach is that the certificate does not contain the private key. i.e. certFromCertificate.HasPrivateKey is false.
My Questions
Why does certFromSecret have the PrivateKey, while certFromCertificate doesn't?
How can I retrieve a certificate from the key vault, where I can create a X509Certificate2 object to host my application in Kestrel with UseHttps.
On the Key Vault properties pages, select Certificates. Click on Generate/Import. On the Create a certificate screen choose the following values: Method of Certificate Creation: Generate.
Under Private key source, select Azure Vault . Fill these input fields with the values you noted down when setting up the Azure Key Vault with the private key. Under Password, enter the password that you set when creating an Azure Key Vault with a private key. Click Import.
Azure Key Vault is a cloud service that provides a secure store for secrets. You can securely store keys, passwords, certificates, and other secrets. Azure key vaults may be created and managed through the Azure portal.
Generate the Client ID Login to the Azure portal. Search for Azure Key Vault. Click +Add to create a new key vault as shown below: After the vault is created, from the left navigation, select the Overview section and make note of the Vault URI AZURE_KEYVAULT_URL.
The 2nd part of @Adrian's answer explains the concepts around the Azure KV Certificates very well, and I have changed my code as below to get the full certificate including the private keys:
SecretBundle secret = await kv.GetSecretAsync(keyVaultUrl, certName);
X509Certificate2 certificate =
new X509Certificate2(Convert.FromBase64String(secret.Value));
The trick was to use GetSecretAsync
instead of GetCertificateAsync
. Please refer to Adrian's SO answer to see why the secret had to be used to get the full certificate with Private keys.
Note that you should use "Certificate identifier" property (url with "/secrets/") from Azure certificate's property page.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With