Search code examples
sslasp.net-corex509certificate2azure-keyvaultkestrel

Kestrel Secure HTTPS X509 Cert from KeyVault


I want to secure my API with a pfx cert which I have stored in my KeyVault however for some reason this doesn't seem to work the way I expected. If I have the cert installed on my machine it works perfectly. I was wondering if its possible to store the cert in KeyVault and then secure it this way as opposed to looking it up in the certificate store.

The scenario is I have a .NET Core Web API which talks to KeyVault. This KeyVault contains my PFX certificate, which when I uploaded prompted for my password. So everything seems fine at this point.

I have the following code to retrieve and apply the cert:

            var client = new KeyVaultClient(new KeyVaultCredential(GetToken));
            var cert = client.GetCertificateAsync("https://somekeyvaultsomewhere.vault.azure.net/", "my_tls_cert").Result;
            var certificate = new X509Certificate2(cert.Cer);

            var host = new WebHostBuilder()
                .UseKestrel(options =>
                {
                    const int PortNumber = 5001;
                    options.Listen(
                        new IPEndPoint(IPAddress.Any, PortNumber),
                        listenOptions =>
                        {
                            listenOptions.KestrelServerOptions.AddServerHeader = false;
                            listenOptions.UseHttps(certificate);
                        });
                })
                .CaptureStartupErrors(true)
                .UseStartup<Startup>()
                .Build();

            host.Run();

I am expecting to be able to hit my API via https and on port 5001. Instead I get no response (site cannot be reached).

Seems like everything is running but can't hit anything.

enter image description here

Is this possible to do?

Packages consumed:

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="2.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions" Version="2.1.3" />
  </ItemGroup>

Solution

  • I think this is because the certificate that you have downloaded is not the complete certificate, but only the public key. The lack of a private key will prevent the SSL handshake from completing. You can download the entire certificate as a secret and then convert the secret to an X509Certificate2 object. I've explained in this blog post:

    https://azidentity.azurewebsites.net/post/2018/07/03/azure-key-vault-certificates-are-secrets