DigitallyCreated
Blog

Only showing posts tagged with "Certificates"

Removing a Windows System Certificate Store

Recently I managed to add an extra certificate store to Windows by mistake, as I accidentally left out a command line argument when using makecert. Unfortunately, the Certificates MMC snap-in doesn’t seem to provide a way for you to delete a certificate store, so I had resort to a more technical approach in order to get rid of this new unwanted certificate store.

Certificate Store Mistake

Digging around in the Windows API, I found the CertUnregisterSystemStore function that allows you to delete a certificate store programmatically. So I spun up my copy of LINQPad so that I could quickly script in C# and PInvoke that function. (Incidentally, if you don’t have a copy of LINQPad and you’re a .NET developer, you need to get yourself a copy immediately. It’s invaluable.) Unfortunately, CertUnregisterSystemStore takes a flags parameter, and the actual values of the different flags are defined in C++ .h files, which are not available from C#. So I punched out a few PowerShell commands to search the .h files in the Windows SDK for those #define lines.

Searching for flag values using PowerShell

Once those flag values were found, deleting the store ended up being this small C# script in LINQPad that simply calls CertUnregisterSystemStore with the appropriate flags:

void Main()
{
    int CERT_SYSTEM_STORE_LOCATION_SHIFT = 16;
    uint CERT_SYSTEM_STORE_CURRENT_USER_ID = 1;
    uint CERT_SYSTEM_STORE_LOCAL_MACHINE_ID = 2;
    
    uint CERT_STORE_DELETE_FLAG = 0x10;    
    uint CERT_SYSTEM_STORE_CURRENT_USER = CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT;
    uint CERT_SYSTEM_STORE_LOCAL_MACHINE = CERT_SYSTEM_STORE_LOCAL_MACHINE_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT;
    
    CertUnregisterSystemStore("TestCertificate.cer", CERT_STORE_DELETE_FLAG | CERT_SYSTEM_STORE_CURRENT_USER);
}

[DllImport("crypt32.dll", CharSet = CharSet.Unicode)]
public static extern bool CertUnregisterSystemStore(string systemStore, uint flags);

I’ve also included the flags needed to delete stores from the local machine (as opposed to the current user account) in the script above, in case anyone ever needs to do that.

Using Makecert to Create Certificates for Development

When I first needed to use certificates to secure my WCF service, I didn't really understand how certificates worked, how to create them, and where they go. A lot of the tutorials on the web just give you a raw makecert command that you black-box and trust works to create your certificate. But do you really know what it's doing? This is what I will explain today, although not in excruciating detail. Just enough to know what's going on.

Firstly, a few concepts. Certificates are a type of identification that try to ensure that you know who you are talking to, and that it is not somebody else just impersonating the person you are expecting to be talking to. In more technical terms, a certificate binds together a name (an identity) and a public key.

But if anyone could just create their own certificates, they could declare themselves to be anyone, right? For example, I could create a certificate whose name is "google.com", but I'm not really Google. This is where Certificate Authorities step in. These organisations are able to issue certificates to people, thereby ensuring that the identity declared on the certificate is actually the identity of the person holding the certificate. For example, if I went to Thawte (or some other authority) and said I wanted a certificate for "google.com", they would tell me to get stuffed (perhaps more politely, though).

So how does this authority-issuing-thing work? A certificate authority themselves have a certificate with which they digitally sign all the certificates they issue. My computer (and pretty much everyone's) has a store of the certificates of these different certificate authorities. The computer then knows that if its sees any certificate that has been signed by one of these trusted certificate authorities' certificate, then the computer should trust that certificate. This concept is called "Chain Trust". The "chain" part refers to the "chain" of certificates-signing-certificates.

So during development, we may want to create certificates for our own purposes and then implicitly trust them. We don't really want to go to a certificate authority and get a signed certificate, because that costs money and we're cheap. Instead, what we can do is create our own certificate authority and then issue certificates to ourselves to use. We place this fake certificate authority's certificate in our computer's trusted certificate authorities store thereby causing our computer to implicitly trust all the certificates that we issue from that authority.

Note that this opens up a security hole on your PC, because if anyone was able to get a hold of your certificate authority certificate (and its private key, with which you sign certificates), they could create certificates that your computer would silently trust. Of course, this isn't too big a deal if you just slap a nice big password on your private key, and when you're finished developing, remove the fake certificate authority certificate from your trusted certificate store.

To see what certificates you currently have on your PC, open MMC (Run->mmc.exe), click "File->Add/Remove Snap-in", select Certificates from the left list, click "Add". Select "My user account", which will mean the snapin will show certificates that are stored specifically for your Windows user account. Select Certificates from the list again and "Add" it, then this time select "Computer account". This snapin will show certificates belonging to the machine specifically, and will apply across all accounts. Press Finish, then OK. I suggest you Save this MMC arrangement, so you can get back to it more easily in the future (File->Save).

Expand "Certificates (Local Computer)\Trusted Root Certification Authorities\Certificates". This folder shows you all the Certificate Authorities that your computer trusts.

So now we need to create our own Certificate Authority certificate. Open the Visual Studio Command Prompt as Administrator. CD to some place you want to store your certificate files. Here's the command for makecert to create your certificate authority, along with an explanation of each of the options you pass to makecert:

makecert -n "CN=My Awesome Certificate Authority" 
         -cy authority 
         -a sha1 
         -sv "My Awesome Certificate Authority Private Key.pvk"
         -r
         "My Awesome Certificate Authority.cer"
         
  -n            : The certificate name. CN stands for Common Name and is the name that 
                  identifies the certificate. For websites, this is their domain name.
  -cy authority : Creates a certificate authority certificate
  -a sha1       : Use the SHA1 algorithm
  -sv           : The private key to use, or create.
  -r            : Create a self-signed certificate (so that you are the root of the certificate chain)
  *.cer         : The filename to export to

Because you haven't created a private key before, the -sv option will create you one. Therefore, Makecert will ask you for a password that will lock the private key. Provide a nice strong one. When it then goes to use the private key, it asks you to re-provide that same password.

You can now install your new certificate authority certificate into the trusted store. To do this, simply go to your MMC console, right click on "Trusted Root Certification Authorities", go "All Tasks", then "Import". Select your new certificate, and when it asks you where to put the certificate, ensure that it goes into "Trusted Root Certification Authorities". Your computer now implicitly trusts all certificates signed by that new certificate authority.

Now we need to create a client certificate that is signed by our new certificate authority. You can do this one of two ways. The first way is to create a certificate and store it and its private key in the Windows Certificate Store (what you see in MMC). This is how you do that:

makecert -n "CN=myawesomesite.com" 
         -ic "My Awesome Certificate Authority.cer" 
         -iv "My Awesome Certificate Authority Private Key.pvk"
         -a sha1
         -sky exchange
         -pe
         -sr currentuser
         -ss my
         "myawesomesite.cer"
         
  -n            : The certificate name. CN stands for Common Name and is the name that 
                  identifies the certificate. For websites, this is their domain name.
  -ic           : The certificate to use as the root authority
  -iv           : The private key of the root authority certificate
  -a sha1       : Use the SHA1 algorithm
  -sky exchange : Create a certificate that can do key exchange
  -pe           : Makes the certificate's private key exportable
  -sr           : The certificate store location to hold the certificate (currentuser or localmachine)
  -ss           : The certificate store name. my is the Personal store
  *.cer         : The filename to export to

It will ask you for the certificate authority's private key's password, so that it can use the private key to sign your certificate. It then will store your certificate (and its private key) in the current user's Personal store. You should be able to see it in MMC. It will also create a copy of the certificate on the hard drive.

The other way you can create the certificate is to create it and its private key as files on the hard drive. You can then combine them into a single PFX (Personal Information Exchange) file, which can be imported into your certificate store if you wish. To do this, run this makecert command:

makecert -n "CN=myawesomesite.com" 
         -ic "My Awesome Certificate Authority.cer" 
         -iv "My Awesome Certificate Authority Private Key.pvk"
         -a sha1
         -sky exchange
         -pe
         -sv "myawesomesite.com Private Key.pvk"
         "myawesomesite.com.cer"
         
  -n            : The certificate name. CN stands for Common Name and is the name that 
                  identifies the certificate. For websites, this is their domain name.
  -ic           : The certificate to use as the root authority
  -iv           : The private key of the root authority certificate
  -a sha1       : Use the SHA1 algorithm
  -sky exchange : Create a certificate that can do key exchange
  -pe           : Makes the certificate's private key exportable
  -sv           : The private key to use, or create.
  *.cer         : The filename to export to

This will ask you for a password with which to lock the new private key you are creating for this certificate. It will also ask you for the password to the certificate authority's private key. It creates your certificate on the hard drive and also the private key in a PVK file.

To combine the private key and the certificate into a PFX file, run this command (this uses pvk2pfx):

pvk2pfx -pvk "myawesomesite.com Private Key.pvk" 
        -spc "myawesomesite.cer" 
        -pfx "myawesomesite.pfx" 
        -pi YourPassword
  
  -pvk : The PVK file to lock away in the PFX
  -spc : The certificate to put in the PFX
  -pfx : The PFX file to create
  -pi : The password of the private key

This will create your PFX file, which you can import into your Personal store using MMC in a similar fashion as you did with the certificate authority certificate.

And that's it. You now have a trusted certificate authority and a certificate that is signed by that authority in your computer's store. You can now use them for development (for example, for WCF service security).