1

I have been trying to add https to my website, which is bound to a domain. Therefore, I tried certbot to generate my certificates. I have tested those certificates on my mock server written in js. There, all I had to do was provide specific options to Express server like following:

var options = {
   key: fs.readFileSync('privkey.pem'),
   cert: fs.readFileSync('fullchain.pem')
};

Poof, a lock appeared at my browser's link tab, saying my website is secure. Now I wanted to move it to ASP.NET Core, so I found kestrel options, where I can provide my certificate:

Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{  
    webBuilder.UseStartup<Startup>();
    webBuilder.ConfigureKestrel(o =>
    {
        o.ConfigureHttpsDefaults(ohttps =>
        {
            ohttps.ClientCertificateMode = Microsoft.AspNetCore.Server.Kestrel.Https.ClientCertificateMode.RequireCertificate;
            ohttps.ServerCertificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(...);
        });
    });
});

However it seems like I only have to provide X509 Certificate, which is a public certificate. Isn't a private certificate needed for server to provide safe connection? Do I have to use a private certificate? How to implement it in ASP.NET Core? (3.1)

大陸北方網友
  • 3,696
  • 3
  • 12
  • 37
sinaC
  • 149
  • 1
  • 7

2 Answers2

1

I'm configuring the Kestrel HTTPS options with .UseKestrel. But the options can also be set in the .ConfigureKestrel method.

In the example, I'm loading the cert from a Windows Servers certificate store.

But there is also an overload of UseHttps(ListenOptions, String, String) which accepts a filename and a password. (see the docs )

new WebHostBuilder()
.UseKestrel(opt =>
{
        int port = endpointConfig.Port;
        opt.Listen(IPAddress.IPv6Any, port, listenOptions =>
        {
            listenOptions.UseHttps(GetCertificateFromStore(certThumbprint, certStore));
        });
})
.ConfigureServices(
    services => services
        .AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
Aristos
  • 66,005
  • 16
  • 114
  • 150
johnmoarr
  • 430
  • 3
  • 7
0

Thanks to johnmoarr's answer and this answer I was able to figure this out. Key provided to .UseHttps() method must be public key paired up with private key, which can be achieved by generating it with openssl:

openssl pkcs12 -export -out key.pfx -inkey privkey.pem -in fullchain.pem

Then, the generated file key.pfx can be used in kestrel builder method, along with password provided in certificate export:

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder
        .UseStartup<Startup>()
        .UseKestrel(o =>
        {
            o.Listen(IPAddress.Any, 443, opt =>
            {
                 opt.UseHttps("YOUR_PATH/key.pfx", "YOUR_EXPORT_PASSWORD");
            });
        });
    });

Furthermore, you can even test it on your local computer, putting your LAN IP and domain name in hosts file.

sinaC
  • 149
  • 1
  • 7