Sunday, June 1, 2014

Practical Certificate Knowledge for .NET developers: Generating Your Own Certificates

Generating Your Own Certificates


Last week's post was an introduction to practical certificate knowledge in windows. This week we're going to look at generating your own certificates as a learning exercise. 

Introduction

First, we're going to create a new root certificate using the makecert.exe utility. Remember, a root certificate is also called a self-signed certificate, as this is a certificate that isn't signed by another certificate (technically, it is signed by its own private key). Then, we'll install this root certificate into the trusted root certificate authority area in Windows. That means the generated root certificate will be trusted, and any certificate we create signed by the generated root certificate will be trusted. 

After that, we'll create a cert that is signed by the root cert and examine the trust chain for it. Lastly, we'll leverage the pvk2pfx.exe utility to create a .pfx (or personal information exchange) file that we can import into the personal certificate store. 

Also, one terminology piece to cover: you may have heard the terms 'valid' and 'trusted' when referring to certificates. Trusted means that you can trace the chain of trust of a certificate back to a root certificate that is trusted (in Windows, this means it's in your Trusted Root Certification Authority). Generally speaking, valid means that a certificate is trusted, is not expired, and is not revoked. I briefly touch on revocation at the bottom of this post.

Utilities required

makecert.exe: In order to generate a self-signed certificate, you'll need the makecert.exe utility for Windows. This utility ships with Windows SDKs, for example, I found it in C:\Program Files (x86)\Windows Kits\8.1\bin\x64 as well as a few other locations. You can find its official documentation here. I'll go over each flag we use with the makecert command, or you can refer to the official documentation.

pvk2pfx.exe: A .pvk file is a private key file. A .pfx file is a personal information exchange file, which contains information including certificates and private keys. These files may be password protected to ensure that even if someone accidentally sends out a .pfx file, they can't get to the private key without knowing the password. You can find the official pvk2pfx.exe documentation here.

Ensure you get these utilities directly from Microsoft. You wouldn't want to generate certificates with a tampered program, so you can verify the authenticity of your utilities by right clicking on them, selecting properties, and viewing the Digital Signature tab to ensure the utilities are digitally signed by Microsoft.

Generating a root (or self-signed) certificate

Let's generate a root certificate. makecert.exe is a standalone utility, so you can feel free to copy it to another directory to generate certificates in, along with pvk2pfx.exe. Your directory should look something like:



Open up a command prompt (Win+R, type 'cmd', press <enter>) and navigate to the location of makecert.exe. An easier way to do this might be to navigate to the location in windows explorer, then shift+right click in the directory and select 'Open Command Window Here' (note you cannot have any files selected when right clicking, or you'll get the file menu instead of the directory menu). 

We're going to run the following command, but before we do that, you can read about what all the parameters mean just below it.

makecert.exe -r -n "CN=MyRootCert" -pe -sv MyRootCert.pvk -len 2048 -b 05/21/2014 -e 05/21/2029 -cy authority MyRootCert.cer

-r: This indicates the certificate is self-signed (also known as a root certificate). 
-n "CN=MyRootCert": The certificate name. This must conform to X.509 standards - an simple way to do this is to start the name with CN=.
-pe Indicates the private key is exportable.
-sv "MyRootCert.pvk": The name of the private key file - one is generated if you do not provide one.
-len 2048: the key length. RSA claimed that 1024-bit keys were likely to become crackable some time between 2006 and 2010 (they were right - they were cracked in 2010) and that 2048-bit keys are sufficient until 2030. If you need further security, increase the key length. In fact, NIST, the National Institute of Standards and Technology, has stated that 1024 bit keys should no longer be used past 2013, so do not use them in a production environment. 
-b and -e with dates: the begin date and end date that the cert is valid. 
-cy authority: This value can be authority or end-entity. authority indicates that this cert can be used to sign other certs. end-entity indicates this cert cannot be used to sign other certificates, thus forcing it to be the end of a trust chain.
Finally, MyRootCert.cer indicates the name of the output file.

Alright, now that we understand what we're running, let's go ahead and run the command. The first thing that happens is the utility creates the private key file. When this happens, you'll be asked to set a password. What this lets you do is protect the private key file with a password if you so choose, so if someone gets the private key file, they still can't use it without the password. In our case, since we're learning, set the password to 'learning', or don't set one at all.




If you set a password, you'll immediately be prompted to re-enter it. Before entering it, take a look at your directory.


See the .pvk file? Your private key file has already been generated, and now the utility wants to use the .pvk file to sign the .cer file (hence this being a self-signed certificate). Since you password-protected your .pvk file, you have to authorize the use of it. Enter the password and click ok. 

Once again, look at your directory. You should now see the .cer file there. Go ahead and double click it. Now you'll see the following: 




You generated your first certificate, but it's not trusted yet. Let's also look at the certification path tab. This tab will let you trace a certificate's chain of trust back to its root certificate. In this case, we only see one cert, as this is the root - later, we'll see more for other certs. Also note the status field text - this will change once our cert is trusted.





Trusting the root certificate

We want to trust the root certificate so that any cert you sign with it is also trusted by your machine. In order to do this, we need to install it in the Trusted Root Authority Certificate that we looked at in last week's post. Go ahead and return to your certificate management console. 

Once there, right click on the Trusted Root Certificate Authority->Certificates folder, select "All Tasks", then "Import." Go ahead and hit next, then browse to find your MyRootCert.cer certificate, and hit next. Select the 'Place all certificates in the following store' option, and ensure the store is set to 'Trusted Root Certification Authority'. Hit next, then finish. You'll get a warning about installing the root cert. Read it over, and click yes - in a real world scenario you'll want to validate the information displayed is correct. Once the import completes, validate that you see the MyRootCert certificate in the certificate manager. 

Now go back to your directory where you generated the cert and double click on the cert again. You should now see the cert has some purposes, and the certification path tab should say 'this certificate is ok', which indicates that it's valid (meaning it's trusted, not expired, and not revoked - more on revocation later). 





Creating a certificate signed by the root cert

Let's look at a new command that'll generate a cert signed by our root cert.

makecert.exe -iv MyRootCert.pvk -ic MyRootCert.cer -n CN=MySecondCert -len 2048 -pe -sv MySecondCert.pvk  -sky exchange -b 01/21/2010 -e 01/21/2020 MySecondCert.cer -eku 1.3.6.1.5.5.7.3.1

Before running this, let's look at the new flags that are being used.

-iv: The issuer's private key file. Required to generate a signed certificate.
-ic: The issuer's .cer public key file. Required to generate a signed certificate.
-skySpecifies the subject's key type, which must be one of the following: signature (which indicates that the key is used for a digital signature), exchange (which indicates that the key is used for key encryption and key exchange).
-eku: Specifies the extended key usage (sometimes referred to as enhanced key usage). Extended Key Usage can set be server authentication (a constant value of 1.3.6.1.5.5.7.3.1) or client authentication (a constant value of 1.3.6.1.5.5.7.3.2). There are additional values for different purposes. In our example, we are generating a server cert, one of the uses of which is an SSL cert. 

Go ahead and run the command. You'll be prompted to enter a password. Enter 'learning' again for the password (then re-enter it when you're prompted for it again). Your directory should now contain a MySecondCert.cer and MySecondCert.pvk. Double click the MySecondCert.cer file and click on the certification path. You should see:



Note that you can follow the Certification Path back to the root certificate, and your new cert is already trusted, since it's signed by MyRootCert, which is in your Trusted Root Certification Authority. 'This certificate is OK' means that the certificate is valid (which if you remember, means trusted, not expired, and not revoked).


Importing into your Personal store

The personal store in the certificate manager should contain your public and private key pairs in order to decrypt messages sent to you that have been encrypted by your public key.

In order to do this, we're going to create a .pfx file. If you recall from last time, a .pfx file is a Personal Information Exchange file. This can be used to combine your public and private keypair into a single file, and import this into your personal store. See the official Microsoft definition below in the first entry.



We're going to use the pvk2pfx.exe utility to create the .pfx file. The official documentation for this utility can be found here.

This command will generate a .pfx file for MySecondCert.

pvk2pfx -pvk MySecondCert.pvk -pi learning -spc MySecondCert.cer -pfx MySecondCert.pfx

-pvk: This specifies the private key file to use.
-pi: This specifies the password for the private key file. In our example, I'm assuming you used the 'learning' password. If not, change the password in the command, or remove the -pi learning flag entirely if you did not use a password.
-spc: This specifies the public key certificate.
-pfx: This specifies the output file name.

After running this command, you should see a .pfx file in your directory. Double clicking it will let you import this file into your Personal store. Follow the wizard until you get to the screen where you enter the password. There are a few protection options here to ensure your private key does not get accidentally exported or used without your consent. In our case, let's keep the following configuration:



On the next screen, explicitly specify the Personal store (this is where the key should go anyways, even if Windows selects the correct store). 

Open your certificate manager. You should now see this cert in your personal store. 

Re-exporting the certificate as a base-64 encoded string

One more thing you may come across is the requirement to provide a certificate as a string of characters rather than the .cer file itself. In order to get this, head to your certificate store and export a certificate in Base64 format (if it is a cert in your personal store, do not export the private key). Once the cert is exported, go ahead and open it in notepad. You'll see -----BEGIN CERTIFICATE----- followed by the base-64 encoded string representation of the certificate, followed by -----END CERTIFICATE-----. You can now supply the base-64 encoded string representation of the certificate.

I now know that this format of a certifcate (between the BEGIN and END lines) is called PEM, or sometimes ASCII Armor, thanks to Maarten Bodewes. Thanks Maarten!

Revocation

Certificate authorities have the ability to revoke a certificate and publish lists of revoked certificates online. This means that if a certificate becomes compromised (for example, if someone steals a certificate's associated private key), the CA can add the cert to a revocation list. In order for a cert to be valid, it cannot be on a revocation list. If you write any code that checks the validity of a cert, ensure you check the revocation list instead. This can pose a challenge and security risk if you are working in an scenario where the server running the code to validate a certificate does not have access to the internet. You can read more on revocation on Wikipedia.

Conclusion

Alright, I hope that this post was able to teach you something about practical usage of certificates. I know there are probably still plenty of questions, like "how do I use these certs to secure a site?" and "how do I use these certificates in C#?", which I hope to cover in future posts.

One last note: ensure you now keep your .pfx and .pvk files to yourself. Don't share them with anyone. If someone gets a hold of your root cert and private key, they can present certs to you that you'll implicitly trust, which would be very bad news. If you want to be safer, clean up your certificate store by removing the MySecondCert entry from your personal store, and the MyRootCert from the Trusted Root Certification Authorities.

No comments:

Post a Comment