- Generating self-signed certificates on Windows
- 1. PowerShell 4.0
- 2. OpenSSL
- 3. Makecert
- 4. Selfssl7
- 5. IIS
- 6. Pluralsight
- 7. SelfSSL
- 8. SSLChecker
- 9. Hard core
- 10. mkcert
- Generate self-signed certificates with the .NET CLI
- Prerequisites
- Prepare sample app
- .NET Core 3.1 sample app
- .NET 5 sample app
- Create a self-signed certificate
- With dotnet dev-certs
- Clean up
- With PowerShell
- Clean up
- With OpenSSL
- Clean up
Generating self-signed certificates on Windows
If you do anything with Identity, you’ll know you need certificates — lots of them — and that normally means self-signed to keep the costs down or because you just need it for a short time before you tear down the VM or because you don’t have a PKI infrastructure.
This is for testing, proofs of concept etc. This is definitely not for Production purposes. Use at your own risk.
This self-signed certificate also needs a private key otherwise it’s pretty useless for SSL, token signing etc.
Remember that this won’t be signed by a CA so you need to do this to stop the browser complaining once you’ve generated the certificates.
Note: The “ character displayed by Medium does something funny when you cut and paste and run the command. You need to retype it as a “straight” character.
Just calling out Let’s Encrypt. They provide free CA certificates that support multiple SAN and wildcards. The drawback is that the certificate is only valid for 90 days but they provide an automated renew process. This is a very good option for a quick PoC.
So, what other options do we have?
1. PowerShell 4.0
Running as administrator.
$cert = New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname company.co.nz
Using “mmc”, we can see the certificate in the local computer store. Although it shows “Client Authentication”, it is valid for “Server Authentication” as well.
Now we can do the normal export function or we can create the pfx file ourselves.
$pwd = ConvertTo-SecureString -String ‘password1234’ -Force -AsPlainText
$path = ‘cert:\localMachine\my\’ + $cert.thumbprint
Export-PfxCertificate -cert $path -FilePath c:\junk\certificate\powershellcert.pfx -Password $pwd
and then double-click the pfx file to import via the “Certificate Import Wizard”. You’ll be asked to input the password you used above.
This certificate is only valid for a year (the default).
If we wanted a three-year certificate, we need:
$date_now = Get-Date
$extended_date = $date_now.AddYears(3)
$cert = New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname company.co.nz -notafter $extended_date
Now what happens if we need multiple SAN (subject alternative name)?
“-DnsName” specifies one or more DNS names to put into the subject alternative name extension of the certificate. The first DNS name is also saved as the Subject Name.
$cert = New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname company.co.nz, mycompany.co.nz, minecompany.co.nz -notafter $extended_date -KeyLength 4096
And note the keylength parameter if that’s something you need to change.
2. OpenSSL
Originally for the Linux world but you can get a Windows version from Shining Light. Don’t worry about the Win32 reference and the outdated documentation at the top. Scroll down and you’ll see the latest Win64 stuff.
And help with future work by donating $10 😄. It’s a lot easier than having to compile the binaries!
openssl version -a
gives you the version.
openssl req -x509 -newkey rsa:4096 -sha256 -keyout openssl.key -out openssl.crt -subj “/CN=company.co.nz” -days 600
Generating a 4096 bit RSA private key
…………………………………++
…………………………++
writing new private key to ‘opensll.key’
Enter PEM pass phrase:
Verifying — Enter PEM pass phrase:
The crt file is the same as a cer file. You can use it in Windows e.g. to load a signing key for another claims provider in ADFS.
But it doesn’t contain a private key — that’s in a separate file — and Windows doesn’t like that. See below for steps on combining them.
As far as multiple SAN are concerned, OpenSSL currently doesn’t support a way of doing this via the command line.
I believe this is coming in 1.1.1 via:
extension “subjectAltName = DNS:mycompany.co.nz, DNS:minecompany.co.nz”
At the moment, you need to do this via a configuration file.
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = NZ
ST = NI
L = Auckland
O = Company
OU = Division
CN = company.co.nz
[v3_req]
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = company.co.nz
DNS.2 = mycompany.com
DNS.3 = minecompany.co.nz
Save this as “san.cnf”.
openssl req -x509 -newkey rsa:4096 -sha256 -keyout opensll.key -out openssl.crt -days 600 -config san.cnf
To make this available to Windows, you need to combine the private and public keys into one pfx file.
openssl pkcs12 -export -name “company.co.nz” -out openssl.pfx -inkey openssl.key -in openssl.crt
where “company.co.nz” is the friendly name.
3. Makecert
As per the documentation, makecert is deprecated and you should use the PowerShell command as above.
Official documentation is here.
To make a self-signed certificate with a private key, use:
makecert -r -pe -n “CN=company.co.nz” -e 01/01/2019 -sky exchange -sv makecert.pvk makecert.cer
“C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin\pvk
2pfx.exe” -pvk makecert.pvk -spc makecert.cer -pfx makecert.pfx
(The path to pvk2pfx is as per my PC. YMMV).
Then install the pfx file.
4. Selfssl7
This used to be my go-to tool for generating self-signed certificates.
The current version runs on .NET 3.5 that is not normally installed on the latest servers and PC’s. You can download the code and rebuild for .NET 4.6 and it will work just fine.
One of the best features for me was that it could do the IIS SSL bindings as well as installing the certificate into the appropriate store.
SelfSSL7 /N cn=company.co.nz /K 2048 /V 3652 /X /F c:cert.pfx
This generates a self-signed certificate using a 2048 bit-length key, without a password in .pfx format (including the private key)
5. IIS
This is one of those hidden features that very few people know about.
From the top-level in IIS Manager, select “Server Certificates”.
Then click the “Create” on the right.
This will create a self-signed certificate valid for a year with a private key. It is only for “localhost”.
6. Pluralsight
Yes, they are a training company but they also have some neat utilities.
You can create a PFX file directly or you can save directly to a certificate store of your choice.
7. SelfSSL
This is an old-school utility which is available if you have the Microsoft Internet Information Services (IIS) 6.0 Resource Kit.
selfssl /t /v:200 /n:cn=company.co.nz
The /t option saves you a step by automatically installing the new self-signed SSL certificate into the Web server’s certificate store. The /v option specifies the number of days the certificate will be valid.
8. SSLChecker
This is an online utility.
This will generate a self-signed certificate and a private key in the format:
Save the two texts; call the certificate file “something.crt” and call the private key file “something.key” then use the openssl command above to combine both into a .pfx file that you can then import.
9. Hard core
If you are a developer and insist on rolling your own, there are a number of examples around. .NET doesn’t have the required support so you need to use Bouncy Castle.
10. mkcert
mkcert is a simple tool for making locally-trusted development certificates. It requires no configuration.
“mkcert is written in Go, and you can run it with a Go run command”.
If you have another utility you recommend, note it in a comment and I’ll add it.
The traditional way to look at certificates is to “Run mmc”.
Generate self-signed certificates with the .NET CLI
When using self-signed certificates, there are different ways to create and use them for development and testing scenarios. In this guide, you’ll cover using self-signed certificates with dotnet dev-certs , and other options like PowerShell and OpenSSL .
You can then validate that the certificate will load using an example such as an ASP.NET Core app hosted in a container.
Prerequisites
In the sample, you can utilize either .NET Core 3.1 or .NET 5.
For dotnet dev-certs , be sure to have the appropriate version of .NET installed:
This sample requires Docker 17.06 or later of the Docker client.
Prepare sample app
You’ll need to prepare the sample app depending on which runtime you’d like to use for testing, either .NET Core 3.1 or .NET 5.
For this guide, you’ll use a sample app and make changes where appropriate.
.NET Core 3.1 sample app
Get the sample app.
Navigate to the repository locally and open up the workspace in an editor.
If you’re looking to use dotnet publish parameters to trim the deployment, you should make sure that the appropriate dependencies are included for supporting SSL certificates. Update the dotnet-docker\samples\aspnetapp\aspnetapp.csproj to ensure that the appropriate assemblies are included in the container. For reference, check how to update the .csproj file to support ssl certificates when using trimming for self-contained deployments.
Make sure the aspnetapp.csproj includes the appropriate target framework:
Modify the Dockerfile to make sure the runtime points to .NET Core 3.1:
Make sure you’re pointing to the sample app.
Build the container for testing locally.
.NET 5 sample app
For this guide, the sample aspnetapp should be checked for .NET 5.
Check sample app Dockerfile is using .NET 5.
Depending on the host OS, the ASP.NET runtime may need to be updated. For example, changing from mcr.microsoft.com/dotnet/aspnet:5.0-nanoservercore-2009 AS runtime to mcr.microsoft.com/dotnet/aspnet:5.0-windowsservercore-ltsc2019 AS runtime in the Dockerfile will help with targeting the appropriate Windows runtime.
For example, this will help with testing the certificates on Windows:
If we’re testing the certificates on Linux, you can use the existing Dockerfile.
Make sure the aspnetapp.csproj includes the appropriate target framework:
If you want to use dotnet publish parameters to trim the deployment, make sure that the appropriate dependencies are included for supporting SSL certificates. Update the dotnet-docker\samples\aspnetapp\aspnetapp.csproj to ensure that the appropriate assemblies are included in the container. For reference, check how to update the .csproj file to support ssl certificates when using trimming for self-contained deployments.
Make sure you’re pointing to the sample app.
Build the container for testing locally.
Create a self-signed certificate
You can create a self-signed certificate:
With dotnet dev-certs
You can use dotnet dev-certs to work with self-signed certificates. This example uses a PowerShell console.
The certificate name, in this case aspnetapp.pfx must match the project assembly name. crypticpassword is used as a stand-in for a password of your own choosing. If console returns «A valid HTTPS certificate is already present.», a trusted certificate already exists in your store. It can be exported using MMC Console.
Configure application secrets, for the certificate:
Note: The password must match the password used for the certificate.
Run the container image with ASP.NET Core configured for HTTPS:
Once the application starts, navigate to https://localhost:8001 in your web browser.
Clean up
If the secrets and certificates are not in use, be sure to clean them up.
With PowerShell
You can use PowerShell to generate self-signed certificates. The PKI Client can be used to generate a self-signed certificate.
The certificate will be generated, but for the purposes of testing, should be placed in a cert store for testing in a browser.
At this point, the certificates should be viewable from an MMC snap-in.
You can run the sample container in Windows Subsystem for Linux (WSL):
Note that with the volume mount the file path could be handled differently based on host. For example, in WSL we may replace /c/certs with /mnt/c/certs.
If you’re using the container built earlier for Windows, the run command would look like the following:
Once the application is up, navigate to contoso.com:8001 in a browser.
Be sure that the host entries are updated for contoso.com to answer on the appropriate ip address (for example 127.0.0.1). If the certificate isn’t recognized, make sure that the certificate that is loaded with the container is also trusted on the host, and that there’s appropriate SAN / DNS entries for contoso.com .
Clean up
With OpenSSL
You can use OpenSSL to create self-signed certificates. This example will use WSL / Ubuntu and a bash shell with OpenSSL .
This will generate a .crt and a .key.
To get a .pfx, use the following command:
The .aspnetcore 3.1 example will use .pfx and a password. Starting with the .net 5 runtime, Kestrel can also take .crt and PEM-encoded .key files.
Depending on the host os, the certificate will need to be trusted. On a Linux host, ‘trusting’ the certificate is different and distro dependent.
For the purposes of this guide, here’s an example in Windows using PowerShell:
For .NET Core 3.1, run the following command in WSL:
Starting with .NET 5, Kestrel can take the .crt and PEM-encoded .key files. You can run the sample with the following command for .NET 5:
Note that in WSL, the volume mount path may change depending on the configuration.
For .NET Core 3.1 in Windows, run the following command in Powershell :
For .NET 5 in Windows, run the following command in PowerShell:
Once the application is up, navigate to contoso.com:8001 in a browser.
Be sure that the host entries are updated for contoso.com to answer on the appropriate ip address (for example 127.0.0.1). If the certificate isn’t recognized, make sure that the certificate that is loaded with the container is also trusted on the host, and that there’s appropriate SAN / DNS entries for contoso.com .
Clean up
Be sure to clean up the self-signed certificates once done testing.