Export Azure KeyVault Certificate with Private Key
Last post we manage to extract certificate from Azure KeyVault. Thing is, using such method will only retrieve Public Key of certificate. It is not possible to retrieve Private Key from the method previous used.
Since we are aimimg Private Key, we need to change the way we retrieve certificate. From GetCertificateAsync
to DownloadCertificateAsync
, we can actually download certificate into our memory.
//var certificate = await client.GetCertificeAsync(certName);
var certificate = await client.DownloadCertificateAsync(certName);
But it does not work
Tricky part is, you can not extract Private Key from that.
Even when it shows HasPrivateKey = true
.
When encounter this problem, the scenario is trying to convert the Private Key to AsymmetricKeyParameter
. It supposed to sign my request to the APIs. Which need to do something like this:
Stream stream = new MemoryStream(certificate.Value.Export(X509ContentType.Pkcs12 , certPwd.ToCharArray()));
Pkcs12Store store = new(stream, certPwd.ToCharArray());
string pName = default;
foreach (string n in store.Aliases)
{
if (store.IsKeyEntry(n))
{
pName = n;
Console.WriteLine(n);
}
}
Console.WriteLine(store.GetKey(pName).Key);
As you can see, it needs to store the certificate into Pkcs12Store
which can only be created by using Stream
. when X509ContentType
is not defined when download the certificate, it will not allow you to do such thing. To solve this we need to add X509ContentType.Exportable
into certificate's X509StorageFlags
.
First I tried to add X509StorageFlags
to X509Certificate2
After it's being downloaded, sadly it will not work this way.
The solution
After digging awhile I figure out DownloadCertificateAsync
comes with an option called DownloadCertificateOptions
. Which you can define X509StorageFlags
before download the certificate. After a little bit modification, my code become like this:
DownloadCertificateOptions downloadOption = new(certificateName)
{
KeyStorageFlags = X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.Exportable
};
var certificate = await client.DownloadCertificateAsync(downloadOption);
With this modification, certificate can be exported with Pkcs12
format and convert it to AsymmetricKeyParameter
without any problem.