HTTPS and X509 certificates in .NET Part 2: creating self-signed certificates

Introduction

In the previous post we looked at TLS and certificates in general. We saw what makes up an SSL certificate and how browsers use it to verify the identity of the server and to decrypt/encrypt the communication.

In this post we’ll look at a tool called makecert.exe.

Before we actually continue there are some other important terms that we need to investigate.

Client certificates

In HTTPS we can talk about client and server certificates. You’ll probably know by now that server certificates are used to safely identify a server. That’s what web browsers do when you visit a https:// url.

The other side of the story is client certificates. As the name implies they are used to identify the client in an SSL connection. A client certificate is an optional ingredient in an SSL setup. They are often used in environments which require tight security such as banking or other finance-related businesses that involve payments. Everyday examples of client certificates include ID-cards, VPN or credit cards when you withdraw some money from an ATM.

Client certificates are often used in highly secure environments such as banking or other finance-related businesses. E.g. I received a card reader from my bank that I need to connect to my PC along with a card with a chip in it in case I want to log in to my account. This is called “two factor identification”. The bank’s server can ensure that the request is coming from me and not someone else. It’s possible to set up a web server so that the deployed web application, or at least parts of it, can only be accessed with a client certificate that uniquely identifies a client. Using server and client certificates in an SSL connection will ensure that both parties in the communication are trusted. Both the client and the server will identify themselves with their certificates. You can read more about client certificates and their usage in this example on Wikipedia.

Root certificates

A root certificate is the top certificate in a chain of certificates. It ultimately identifies a Certificate Authority (CA). Each CA, like Big Daddy, has a root certificate which they in turn use to create other certificates. We can trust their certificates because they are signed with the CA’s root certificate. Such a trusted certificate will be digitally signed by the CA.

It’s possible to set up your own root certificate that in turn can be used to create other certificates for different purposes.

Makecert.exe

Makecert is a tool that’s installed with Visual Studio. It is a command line tool that can create all sorts of digital certificates for your private testing purposes. If you open a Visual Studio command prompt, type “makecert” and press Enter you’ll get some basic usage information:

Makecert basic usage printout in command prompt

The tool comes with a long list of options that you can view on MSDN here. We’ll see some of it in action soon. Here’s a list of the most important options that you’ll need to create your own cerificates:

  • -n: certificate name, or “common name”, abbreviated to “CN”
  • -sv: name of the private key file (.pvk)
  • -b: valid from
  • -e: valid to
  • -cy: certificate type, such as root (“authority”) or “end” for the derived certificates
  • -pe: make the certificate exportable, meaning that it will include the private key as well
  • -len: the key length in bytes such as 1024 or 2048 with 2048 being the most frequent setting
  • -r: self-signed
  • -a: the signature algorithm such as SHA1 or
  • -iv: name of the private key file (.pvk) of the root certificate in case you use it to create other certificates
  • -ic: the file name of the root certificate with the extension .cer . -iv and -ic will indicate that you want to sign the new certificate with the digital signature of the root
  • -sky: specifies the key type with two possible values which are “exchange” and “signature”
  • -eku: a comma-separated list of extended key usage object identifiers (OIDs). They look vaguely like invalid IP addresses. This list specifies the purpose of the certificate such as “1.3.6.1.5.5.7.3.1” which stands for “SSL server certificate”, i.e. the one we’ll need for this discussion

We’ll also provide a file name to the certificate which will get the extension “.cer”. Note that both the root and child certificates will have their own private key files of course.

With makecert.exe you can mimic what a real CA would do. You can first create a root certificate which will subsequently be used to create other certificates. Due to the chain of trust – see Wikipedia link above – you can then simply trust the root certificate and implicitly trust all other certificates created with the root due to its digital signature present on the “child” certificates.

Another tool available from the VS command prompt is a packaging tool called pvk2pfx.exe. It packages the .cer and .pvk files into a single file with the extension “.pfx”. Pfx stands for “personal information exchange file”. It will help us later on when exporting files to and from the Windows certificate store.

Creating the certificates

After all this tension build-up we can finally create our root and SSL certificates. Create a dedicated folder where you’ll save the certificates and private key files, e.g. under c:\certificates.

Open a Visual Studio command line tool. Make sure you run it as an Administrator otherwise the file creation steps may fail. Feel free to change the file names along the way for your own testing purposes. Initially the command prompt will probably point to the c:\windows\system32 folder. Navigate to the dedicated certificates folder created above so that the makecert commands will save the files there.

Note: if you simply copy and paste the below commands into the command window you might get a strange exception saying something like “Error: CryptCertStrToNameW failed”. It’s due to WordPress transforming the double-quotes in some way. It’s best if you type in the command by hand. Alternatively you can paste the commands into a word processor and check whether the double quotes look fine.

The following command will create a root certificate called “RootCert”:

makecert.exe -r -n “CN=RootCert” -pe -sv RootCert.pvk -a sha1 -len 2048 -b 01/01/2015 -e 01/01/2030 -cy authority RootCert.cer

It’s imperative that you denote the certificate name with “CN=” in the command. The private key file RootCert.pvk will be created by the command if it doesn’t exist. The final “RootCert.cer” will save the certificate under that file name. You’ll understand the other parameters based on the above list.

When you run the above command you’ll be prompted for a password which will protect our private key. If your root certificate private key is compromised then it is still protected by a password so that no new child certificates can be created from it. It’s OK to provide some easy password that you can remember in this case as this is only a test. It’s equally fine to provide no certificate at all as this is only a test certificate.

If everything goes well you’ll see “succeeded” printed in the command window.

Next let’s package the .pvk and .cer files into a .pfx file using the pvk2pfx.exe tool mentioned above:

pvk2pfx.exe -pvk RootCert.pvk -spc RootCert.cer -pfx RootCert.pfx

You’ll be prompted for the private key password. The RootCert.pfx file will be created.

Let’s now create an SSL certificate using our root. The name is important as it will become the “issued to” field. You cannot just create a certificate with any name like “MickeyMouse”, it must reflect the domain of the web site that will be secured with SSL. To make this clear you can navigate to https://twitter.com and view the certificate information with special emphasis on the Issued To field:

Twitter certificate issued to twitter

It says twitter.com which matches the domain of the URL. If the certificate had been issued to mygreatwebsite.com then you’d get a warning that the server certificate couldn’t be verified and you can continue at your own risk.

The following command will create a child certificate to mylocalsite.local:

makecert.exe -ic RootCert.cer -iv RootCert.pvk -pe -sv mylocalsite.local.pvk -a sha1 -n “CN=mylocalsite.local” -len 2048 -b 01/01/2015 -e 01/01/2030 -sky exchange mylocalsite.local.cer -eku 1.3.6.1.5.5.7.3.1

You’ll again be prompted for a password. If all goes well then you’ll get the same “succeeded” message as above. Let’s also package this derived certificate into a pfx file:

pvk2pfx.exe -pvk mylocalsite.local.pvk -spc mylocalsite.local.cer -pfx mylocalsite.local.pfx

OK, great, we have the necessary certificates to start with. Check the contents of the certificates folder and you should have 6 files in it:

Certificates and private key files created by makecert in dedicated folder

What do we do with these then? We’ll see that in the next post.

You can view the list of posts on Security and Cryptography here.

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

2 Responses to HTTPS and X509 certificates in .NET Part 2: creating self-signed certificates

  1. Pingback: X.509 certificates in .NET | Around computing

  2. Pingback: Using Chained Certificates for Certificate Authentication in ASP.NET Core 3.0 | Software Engineering

Leave a comment

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.