Self signed certificate and configuring Identityserver 4 with certificate

I always forget how to generate self-signed certificates. For once I will now document the process of generating the certificate and also configuring IdentityServer4 with the certificate that I generate. I will also be documenting the process of hosting the IdentityServer in IIS.

Most of these steps are also applied for any application that are using the certificate store. For instance if the user that are running the IIS sites need to do anything with certificate store, it is necessary to load the user profile.

Generate self signed certificates

First time createing a self signed certificate OpenSSL needs to be installed. OpenSSL is, at least in Windows 10, not included by default. OpenSSL can be downloaded from this site. Just pick the openSSL insaller and run the installer.

OpenSSL normally ends up at C:\OpenSSL-Win32 then the bin folder needs to be added to the PATH variable.

SET PATH=%PATH%;C:\OpenSSL-Win32\bin

To create the certificate and the private key with OpenSSL, this command will do the job.

openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout example.key -out example.crt -subj "/CN=example.com" -days 3650
  • req
    The req command creates and process certificates commands in a PKCS#10 format. It is also used to create self signed cerificates. That is what I need to create here.
  • x509
    This outputs a self signed certificate instead of a certificate request. Often that is used when there are needed some test certificates or self signed root certificate.
  • newKey
    This option create a new certificate request and private key.
  • sha256
    This option just say to the newkey that it should use the sha256 algoritm while creating the certificate and private key.
  • nodes
    If a private key is created and nodes argument is speciified it will not be encrupted.
  • keyout
    This is the output private key.
  • out
    This is the output certificate.
  • subj
    This argument sets the subject at the certificate.
  • days
    This argument is only used when x509 is specified. Otherwise it is ignored. It has to be a positive number and will be for how many days the certificate should be valid. Default value is 30.

Generating the certificates can take some time. When it is done there are one private key (.key) and one certificate file (.crt). Those will be used to package up the certifiacte and private key in one pfx file. To create the pfx file it is another OpenSSL command that should be used.

openssl pkcs12 -export -out example.pfx -inkey example.key -in example.crt -certfile example.crt
  • pkcs12

The pkcs12 command allows PKCS#12 files (sometimes referred to as PFX files) to be created and parsed. PKCS#12 files are used by several programs including Netscape, MSIE and MS Outlook. pkcs12

  • export
    This option specify that a pfx file will be created and not parsed.
  • out
    This is the name of the pfx file that will be created.
  • inkey
    This is the private key.
  • in
    This is the certificate file.
  • certfile
    This is the certificate file.

After the pfx file is created that is also the only file that needs to be stored. That can be added to the certificate store in Windows. Normally that is done by using the MMC window.

Install the certificate

To manage certificates at a Windows computer it can be done with the MMC console application. Open the run command window (Win+R key combination) and type mmc. When the console have opened it is time to open the certificate store by adding in the Certificate snap-in from the File menu. I place the certificate in the computer store, but that depends about the needs. If the certificate only should be used by the logged in user, that will work as well.

The certificate that have been generated and should be used by Identityserver should be placed in the Personal certificate store (folder). Right click on Personal and pich Task -> Import. Since the certificate is pached with the private key in a pfx file, the drop down at the bottom right corner need to be changed so the certifiacte is visible. Then just click next and add the password for the certificate when it is prompted.

managecertprivatekeys

The last thing to do now is to make sure that the user that should run the IdentityServer have access to the private key. In the image above there are the context menu when the certificate is right clicked. Choose the Manage Private Keys option. There it is possible to add a user permission to the private key. It is probably enough with read access in most cases.

Using the certificate in IdentityServer4

First we need to get the certificate from the certificate store.

X509Certificate2 cert = null;
using (var certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine))
{
    certStore.Open(OpenFlags.ReadOnly);
    var certCollection = certStore.Certificates.Find(
        X509FindType.FindByThumbprint,
        "<THUMBPRINT>", // Change this with the thumbprint of your certifiacte
        false);

    if (certCollection.Count > 0)
    {
        cert = certCollection[0];
    }
}

Always when reading from certificate store, opening the store is important. There are no error messages if the store is not opened. certStore.Open(OpenFlags.ReadOnly); Last time I forgot this line, the certificate collection always returned an empty result set. That means no certificates. That is frustrating at so many levels since I thought I did it right, but for some reasons was not able to retrive any certificates.

if(cert == null)
{
    // If the certificate is not installed, you might be in development and want to ise the developer credebntials
    services.AddIdentityServer()
        .AddDeveloperSigningCredential();
}
else
{
    services.AddIdentityServer()
        .AddSigningCredential(cert);
}

Hosting IdentityServer4 in IIS

I normally set up each ASP.Net Core API or websites as its own IIS site. Then I have a own sub-domain for each site. Setting up IdentityServer in IIS is the same as other ASP.Net Core applications.

I will not go in detail on deploying the application to IIS, but just mention the pitfalls I had when deploying. Read the Microsoft documentation for details. Host ASP.NET Core on Windows with IIS

First of all, make sure that the application pool identity that is running the IdentityServer application have access to the private keys. If not it is needed to go back and give it permission.

When I was done deploying, the application was running and everything looked good. I was able to see the openid-configuration document, but when I tried to request a token the logs filled up with certificate errors. After reading the errors it looked like it did not find or did not have permission to get the certificate. I had to go to the application pool and right click and select advanced settings. There I needed to set Load User Profile to true. After I did that and recycled the application pool I was able to use the IdentiotyServer application without errors.

Links

Teis Lindemark

Software developer, beer brewer and AGENT backer

Bergen, Norway https://teilin.net

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.