Free certified SSL certificate in ASP.NET 5 Kestrel application
Tags: ssl, tls, net5, kestrel
Published: 2021-04-10 19:23:04

---
title: Free certified SSL certificate in ASP.NET 5 Kestrel application
published: true
description: It's possible to obtain a free SSL certificate thanks to [Let's Encrypt](https://letsencrypt.org/) but until recently it was not possible to import PEM files directly with .NET core 3.1. It is now possible starting with .NET 5. This feature was introduced in [version 5.0.0-preview8](https://github.com/dotnet/aspnetcore/issues/4706). I'll show you how to configure it.
tags: SSL,TLS,NET5,Kestrel
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6bq6xxgfa7isthf7061b.jpg
---
*Image par <a href="https://pixabay.com/fr/users/skylarvision-2957633/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=3344700">skylarvision</a> de <a href="https://pixabay.com/fr/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=3344700">Pixabay</a>*

As part of a little side project I'm working on, I want to host an ASP.NET Web API on my own server at home. The purpose of this API is to send push notifications to an Angular client application. It is the main reason why I had to set up SSL communication for my web site: service worker needs the communication to be secured by TLS with a valid certificate in order to allow push notications. But that's not the subject of this article. Here I will focus on creating the certificate and loading it into Kestrel.

For the development phase I used a self-signed certificate, but now that I want to deploy it I need a real certificate certified by a certification authority. Because it is not a commercial but personal project I want to keep it entirely free. So I decided to generate a certificate with Let's Encrypt. Until recently, ASP.Net core was only supporting .PFX files and not .PEM files provided by Let's Encrypt. But .NET 5 has [rectified the situation in version 5.0.0-preview8](https://github.com/dotnet/aspnetcore/issues/4706).

> I could use a reverse-proxy like nginx or haproxy and let it handle the SSL stuff, but I wanted to keep it as simple as possible, so I decided to directly serve it using Kestrel.

# Prerequisites

* A domain name that you own. Personally I registered to [Duck DNS](www.duckdns.org) to get a free one.
* An ASP.NET web site binded to your domain (to prove you are the owner of the domain)
* A bash, preferably Linux ;) but Windows is OK too

> Most of Internet providers allow you to configure NAT/PAT and DynDNS, so it should not be a problem to bind your DNS to an open port on a machine in your local network.

# Obtain a free certificate

Most of certification authorities sell their certificates and they are expensive. This is because the process of registering often inquires verification made by a human. Hopefully there is [Let's Encrypt](https://letsencrypt.org/) to the rescue. Let's Encrypt is also a certificate authority but it is nonprofit. It aims to [create a more secure and privacy-respecting Web](https://letsencrypt.org/docs/faq/#what-does-it-cost-to-use-let-s-encrypt-is-it-really-free).

The first thing you have to do is to install [Certbot](https://certbot.eff.org/). There are many ways to do so depending on your system so I won't go into details. The recommanded way is to use snap. Personnaly I simply made a 

```bash
$ sudo apt-get install certbot
```

and it did the job.

Now that you have certbot installed you can generate a new certificate and a private key. Once again there are many ways to do this depending on your server and certbot can be configured to automatically renew your certificate before it expires. Personnaly I used the manual way and will configure autorenew later:

```bash
$ sudo certbot certonly --manual
```

Certbot first ask you what is your domain name and then request you to prove you are in control of it:

```bash
Create a file containing just this data:

eZ4dZ4xUrIn7Fkyuy0Vd9giY5FoEPnm5cfGQXs_EDy0.gj7wCMjUoSpRopo7wvqqw5spi23jZdjLjtlCa00Cf2c

And make it available on your web server at this URL:

http://ssldemo.dev.to/.well-known/acme-challenge/eZ4dZ4xUrIn7Fkyuy0Vd9giY5FoEPnm5cfGQXs_EDy0
```

Modify your website to make the file available at the requested URL and then press ENTER. Certbot will download the file and verify that the content matches with what was requested. It will then issue a new certificate associated with your domain name and the private key used to sign the certicate. Files are created under

```
/etc/letsencrypt/live/ssldemo.dev.to/fullchain.pem
/etc/letsencrypt/live/ssldemo.dev.to/privkey.pem
```

Copy these two files in a secure place on the machine hosting your website and make sure no one can access them except your web application.

# Kestrel configuration

Make sure your website application target at least .NET 5.0. You should have `<TargetFramework>net5.0</TargetFramework>` in your .csproj file.

You now have to instruct Kestrel how to load your certificate. Open appsetting.json file and add a Kestrel section :

```json
  "Kestrel": {
    "Certificates": {
      "Default": {
        "Path": "path/to/fullchain.pem",
        "KeyPath": "path/to/privkey.pem"
      }
    }
  }
```

> You could also use environment variables if you prefer

And that's it ! The method `ConfigureWebHostDefaults` uses Kestrel as the web server so it will use the Kestrel section to configure itself. Just make sure you load appsettings.json at startup (it is the case by default when you use `CreateDefaultBuilder`). Thus, the provided SSL certificate and the private key will be loaded and used by your server. If you don't use `ConfigureWebHostDefaults` then ensure that you have `UseKestrel` on your webBuilder and it should be OK.

Now when you request your web API via HTTPS you should see a valid certificate in the address bar of your web browser:

![address bar with ssl](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcnj02farj9s1xwso369.png)
  
# Conclusion

I wrote this article because I didn't find many documentation on how to configure Kestrel to load PEM SSL certificate. It is my first article and I hope you will find it interesting, maybe even usefull.

If you are interested in, you can find the source code of my current side-project for which I had to load PEM SSL certificate in Kestrel.

* https://github.com/bNobo/wind-forecast-api : the web API
* https://github.com/bNobo/wind-forecast-website : the Angular client