Generating self-signed certificates on Windows

Rory Braybrook
The new control plane
7 min readApr 5, 2018

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

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 -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,, -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!


And there’s a free OpenSSL Cookbook.

openssl version -a

gives you the version.

openssl req -x509 -newkey rsa:4096 -sha256 -keyout openssl.key -out openssl.crt -subj “/” -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 =,”

At the moment, you need to do this via a configuration file.

— — — — — — — —

distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
C = NZ
L = Auckland
O = Company
OU = Division
CN =
keyUsage = critical, digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
DNS.1 =
DNS.2 =
DNS.3 =

— — — — — — — —

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 “” -out openssl.pfx -inkey openssl.key -in openssl.crt

where “” 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 “” -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 /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 /

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.

Here’s one example.

10. mkcert

mkcert is a simple tool for making locally-trusted development certificates. It requires no configuration.

Good write-up here.

“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”.

However you can also use PowerShell and do e.g.:

PS C:\Windows\system32> dir cert:Location   : CurrentUser
StoreNames : {TrustedPublisher, ClientAuthIssuer, Root, UserDS...}
Location : LocalMachine
StoreNames : {TestSignRoot, ClientAuthIssuer, Remote Desktop, Root...}

or e.g.:

PS C:\Windows\system32> dir Cert:\LocalMachine\myPSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\myThumbprint                                Subject
---------- -------
6D30...3C743CCE CN=localhost

All good!



Rory Braybrook
The new control plane

NZ Microsoft Identity dude and MVP. Azure AD/B2C/ADFS/Auth0/identityserver. StackOverflow: Presentations: