Creating Self-Signed Certificates with New-SelfSignedCertificate on Windows 10

December 19, 2018 0 By Toby Worth

I’m using Identity Server 4 and am passing a certificate to the AddSigningCredential() method after calling the AddIdentityServer() middleware.  This certificate provides the key material for creating and validating tokens provided by the secure token server (i.e. my instance of Identity Server 4).

Simple CLI testing

For simple node-based or similar local testing, you can create PEM file and key with OpenSSL that can be used with packages like HTP-SERVER.  The command is simple and quick:

first generate CSR and KEY:

openssl req -new -newkey rsa:4096 -nodes -keyout myapp.key -out myapp.csr

then generate PEM and self-sign with KEY:

openssl x509 -req -sha256 -days 365 -in myapp.csr -signkey myapp.key -out myapp.pem

Then run the server with

http-server -S -C .\myapp.pem -K .\myapp.key

.Net service signing

For development, you can simply use AddDeveloperSigningCredential(), but I prefer to mimic production (within reason) and that means creating a persistent signing certificate with Powershell’s New-SelfSignedCertificate. This has replaced MakeCert (part of Windows SDK) since 2018.  See MakeCert deprecated.

Using a signing certificate with IdentityServer middleware

Example of where you’d use the certificate file in your Startup.cs (in ConfigureServices method):

X509Certificate2 cert = new X509Certificate2(Path.Combine,_environment.ContentRootPath, "mycert.pfx"), "password123");

Obviously, don’t put your certificate in a web-public folder, even for testing.

Creating a Certificate with New-SelfSignedCertificate

There are way too many options and variants to cover in this topic, so we’re just going to focus on this specific use-case, which is server-authentication.   Strangely, this isn’t a first-class citizen of the makecert program, but it’s quite old and presumably predates the now-popular service-oriented/single-sign-on architectures that many SPAs use.

What we’ll need to do to register this cert as a server-authentication type is to apply ‘text extensions’, which uses OIDs to specify one of the extra usage types available.  Generally, we apply the ‘digital signature’ usage, but essentially we’re elaborating on that with the text-extensions.

Here is the command that generates the cert (broken onto separate lines to improve readability).

-Type Custom
-Subject "CN=MyProject, O=Scramjet, C=UK"
-KeyAlgorithm RSA
-KeyLength 2048
-KeyUsage DigitalSignature
-TextExtension @("{text}")
-FriendlyName "STS"
-CertStoreLocation "Cert:\CurrentUser\My"
-NotAfter (Get-Date).AddYears(3)

Most of the options are self-explanatory (refer to the docs if you’re unsure).

The cert store location set here will store the cert at the user’s ‘Personal’ store (as found in the CertMgr snap-in). 

Note: If you want to deploy the project along with this certificate, you’ll need to set this to ‘Cert:\LocalMachine\My’ so it is accessible without your local user account.

Running the command above should return a ‘thumbprint’ and confirmation of your chosen subject. Copy the thumbprint as you’ll use it during export of the PFX file. If you forget to copy it, you can view it in the Certificates snap-in by double-clicking the cert and choosing the ‘Details’ tab.

View your shiny new Certificate

Run mmc.exe from start menu and choose the ‘Certificates’ snap-in.  Select ‘Local User’ from the list of options and you should see your newly created certificate under the ‘Current User/Personal/Certificates’ folder.  You can double click it to examine the details you provided are all there.

Exporting a PFX file from the certificate

You have two options for exporting the file, and they both create the same PFX file, so just go with the one that suits.

Certificates Snap-In Export

You can use the Certificates snap-in to export the certificate to a PFX file, like so:

Right click the certificate, select ‘All tasks’, then ‘Export’.

On the intro screen, click ‘Next’ and choose ‘Yes, Export with Private Key’.

Select the PKCS #12 (.PFX) format and click ‘Next’.

You’ll need to provide a password (which will be necessary later, when applying the certificate).  We’ll use ‘password123’.

Choose a filename and folder for your PFX file (it will default to windows\system32) and finish.

Powershell Export

You can do it in two lines of code with Powershell, which may be useful if you’re scripting multiple certs. See more info here.

$pwd = ConvertTo-SecureString -String password123 -Force -AsPlainText 
Export-PfxCertificate -cert "Cert:\LocalMachine\My\[cert thumbprint]" -FilePath c:\myproj\mycert.pfx -Password $pwd

Using the PFX file

Now we have the PFX file, we can start applying it to the IdentityServer middleware.

X509Certificate2 cert = new X509Certificate2(Path.Combine,_environment.ContentRootPath, "mycert.pfx"), "password123");