.netazurecertificateazure-keyvaultpki

PKI with Azure Key Vault


i have found myself in a situation where i need to issue client certificates for authentication purposes. For that i need a root or intermediate certificate which will sign the client ones. That automatically results in a need for a secure storage for the signing certificate. I have an Azure subscription and it provides a Key Vault, which can store and create certificates. I was happy about the creation part, because it means that i won't have any of the signing certificates on my machine, not even briefly in memory. Or so i thought...

Turns out that Key Vault does not provide any cryptographic operations on the certificate object (Key Vault - Key does for example). This means that i will have to download the whole certificate from the Vault, having the Private Key leave the "secure location". At this point i'm questioning the "secure" part, as in my understanding it should not be possible to export the private key, but it is.

I need a .Net solution, so i have looked at Azure SDK for .Net and Azure Key Vault REST API but they do not provide what i need.

Am a looking in a wrong place or is Azure Key Vault not meant to be used this way?

The simplified (i'll leave out the authentication to all services) workflow i initially thought about is something like:

  1. Create Root (or Root and Intermediate) in a Vault
  2. Create a key pair (RSA.Create() for example)
  3. Create a certificate request (System.Security.Cryptography.X509Certificates.CertificateRequest for example)
  4. Have the request signed by Root (or Intermediate) by sending it to the Vault via Azure SDK (or something equal)
  5. Get signed Request back and use it to create a signed Client Certificate.

But it seems to be not possible.


Solution

  • So the solution that i found is as follows:

    1. Create a private key (with for e.g. openssl)
    2. Create a pfx/p12 certificate with this key
    3. Upload public certificate part as Azure KeyVault Secret
    4. Upload the Key as Azure KeyVault Key object
    5. Create a custom X509SignatureGenerator for either RSA or ECDSA, and use Azure SDK and KeyVault Key object for signing (be careful of correct ASN.1 formatting after signature creation). .Net 6 code is open source so you can look up what standard X509SignatureGenerator do.
    6. Create a Certificate Request in .Net and use custom X509SignatureGenerator
    7. Store the newly created Certificate as is or as X509Certificate2Collection with public certificate part, previously uploaded to Key Vault, to have full chain of Trust.